【问题标题】:Will it be possible to annotate lambda expression in Java 9?是否可以在 Java 9 中注释 lambda 表达式?
【发布时间】:2017-06-20 07:46:39
【问题描述】:

This question 现在已经超过 3 年了,专门针对 Java 8,接受的答案也引用了 Java SE 8 Final Specification

如果有关此问题的某些内容在 Java 9 中会发生变化,我会很感兴趣:是否有任何方法可以注释 lambda 表达式,类似于注释相应的匿名类?


示例:

注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface MyTypeAnnotation {
    public String value();
}

匿名类的工作注解:

Consumer<String> consumer = new @MyTypeAnnotation("Hello ") Consumer<String>() {
    @Override
    public void accept(String str) {
        System.out.println(str);
    }
};

注释一个兰巴表达式,目前在 Java 8 中不工作:

Consumer<String> myAnnotatedConsumer = @MyTypeAnnotation("Hello") (p -> System.out.println(p));

【问题讨论】:

  • 这两个结构之间的一个重要区别是匿名类仍然是类的声明。一个 lambda 表达式不会创建一个新类(或者不一定,如果它是一个实现细节)。我的印象是注释只允许在声明上。 表达式上是否允许使用注释?

标签: java lambda annotations java-9


【解决方案1】:

Stackoverflow 问题的存在不足以表明此类功能已在计划中,甚至没有人曾经考虑它。

如果你查看list of JEPs,你会发现没有这样的JEP,即使处于草案状态,也没有暗示这样的功能。

此外,如果您查看 Java 9 的 LambdaMetafactory 的当前状态,您会发现没有进行任何更改来支持传递元信息,而这些元信息对于生成带有记录注释数据的运行时类是必需的。

似乎有人希望将大量元信息添加到实际上应该是一小段一次性代码中,但我怀疑语言设计者会遵循它。 Lambda 表达式旨在定义一个封装行为的函数,而不是描述匿名类的替代方式。长期的演进将导致 lambda 表达式的实现更不像一个普通的类。

【讨论】:

  • ... are even less of an ordinary class 我等不及要发生这种情况以及为此需要进行的更改
  • Lambda 也不保留其泛型参数,这使得一些依赖反射的框架用例变得困难或不可能。注释可能会有所帮助,所以没有任何一个是不幸的。但我看到了 lambdas 不是类的意义。
  • @MichaelBöckling 请注意,该问题的示例注释了一个 创建站点new 运算符的类型),无论如何都不能通过反射获得。当您注释 lambda 表达式(或其参数类型)的参数时,注释应该可用,但您必须查看相应合成方法的创建者类,而不是运行时生成的类。此外,在我的测试中,只有 Eclipse 产生了可靠的结果,javac 严重失败。另一个障碍是从功能接口的特定实例到相应的目标方法。
  • &gt; getting from a particular instance of a functional interface to the corresponding target method 使用稳定的 API 甚至可以实现吗?如果是这样,这可能会解决我现在遇到的问题。
  • @MichaelBöckling 那是an old issue。简而言之,没有 API(这就是我称之为障碍的原因)。唯一的语言解决方案是强制可序列化函数,因为它们具有命名目标方法的持久表示。否则,我宁愿使用字节码检测。
【解决方案2】:

有趣的是,他们确实通过以下方式注释了“表示”InnerClassLambdaMetafactory.spinInnerClass 中的 lambda 表达式的内部类:

 mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true)

但这显然是在注释一个类,而不是 lambda 本身。

注释 lambda 将需要更改 invokedynamic 和隐含的 LambdaMetafactory 就我所见 - 当 invokedynamic 为 lambda 创建一个类时会发生什么,但是别的东西,那些注释会发生什么?

【讨论】:

    【解决方案3】:

    根据What's new in Oracle JDK 9 页面,没有。这在Java 9 中没有改变。

    当然,这不是确定的,但 Java 9 的 JLS 尚未发布。

    【讨论】:

      猜你喜欢
      • 2017-04-19
      • 2014-09-12
      • 1970-01-01
      • 1970-01-01
      • 2011-03-19
      • 2021-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多