Java 11,为什么我们需要在lambda参数上添加注释?

时间:2018-11-15 13:58:14

标签: java lambda

您知道,Java 11在lambda的参数中添加了使用 var 的功能,以便您可以添加注释,但是这里我尝试在运行时获取它,但是由于lambda是不是具有其方法的成熟类,就不存在。

需要注意的是,它与匿名类很好地配合。

使用匿名类-输出为:

[[@test.MyAnnotation()]]
public class Main {

    public static void main(String[] args) throws NoSuchMethodException {
        Consumer<Integer> consumer = new Consumer<Integer>() {
            @Override
            public void accept(@MyAnnotation Integer integer) {
                System.out.println(integer + 1);
            }
        };

        foo(consumer);
    }

    public static void foo(Consumer<Integer> consumer) throws NoSuchMethodException {
        Method method = consumer.getClass().getMethod("accept", Object.class);
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        System.out.println(Arrays.deepToString(parameterAnnotations));
    }
}

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {

}

使用lambda-输出为:

 [[]]
public class Main {

    public static void main(String[] args) throws NoSuchMethodException {
        Consumer<Integer> consumer = (@MyAnnotation var integer) -> System.out.println(integer + 1);

        foo(consumer);
    }

    public static void foo(Consumer<Integer> consumer) throws NoSuchMethodException {
        Method method = consumer.getClass().getMethod("accept", Object.class);
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        System.out.println(Arrays.deepToString(parameterAnnotations));
    }
}

@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation {

}

你有什么解释吗?

1 个答案:

答案 0 :(得分:1)

注释可以在源代码中用于提供附加信息以及进行注释处理。

我不确定这在运行时是否有用。字节码转储表明未记录注释。

  // access flags 0x9
  public static main([Ljava/lang/String;)V throws java/lang/NoSuchMethodException 
    // parameter  args
   L0
    LINENUMBER 11 L0
    INVOKEDYNAMIC accept()Ljava/util/function/Consumer; [
      // handle kind 0x6 : INVOKESTATIC
      java/lang/invoke/LambdaMetafactory.metafactory(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;
      // arguments:
      (Ljava/lang/Object;)V, 
      // handle kind 0x6 : INVOKESTATIC
      Main.lambda$main$0(Ljava/lang/Integer;)V, 
      (Ljava/lang/Integer;)V
    ]
    ASTORE 1
   L1
    LINENUMBER 13 L1
    ALOAD 1
    INVOKESTATIC Main.foo (Ljava/util/function/Consumer;)V
   L2
    LINENUMBER 14 L2
    RETURN
   L3
    LOCALVARIABLE args [Ljava/lang/String; L0 L3 0
    LOCALVARIABLE consumer Ljava/util/function/Consumer; L1 L3 1
    // signature Ljava/util/function/Consumer<Ljava/lang/Integer;>;
    // declaration: java.util.function.Consumer<java.lang.Integer>
    MAXSTACK = 1
    MAXLOCALS = 2

如果我执行以下操作,它将一无所获。

 strings Main.class | grep MyAnn