关于实例创建的Java 8注释

use*_*234 7 java reflection annotations java-8

在Javadocs for Annotations中,它声明以下内容可以用Java 8编写:

new @Interned MyObject();
Run Code Online (Sandbox Code Playgroud)

无论如何,从通过反射注释的对象中检索注释@Interned?我熟悉从方法,字段,类等中检索注释的典型方法,但我想知道在Java 8中是否可以在运行时将特定实例与注释相关联.

Hol*_*ger 8

施加到一个实例创建像一个注释new @Anno Object()被创建的对象的属性,但仅(编译时间)类型的new表达.在运行时,对象的实际类型没有注释,就像它没有您在创建实例时指定的通用类型参数一样.

请考虑以下示例:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@interface Anno { int value(); }
Run Code Online (Sandbox Code Playgroud)

...

@Anno(1) Object o=new @Anno(2) Object();
@Anno(3) Object p=(@Anno(4) Object)o;
Run Code Online (Sandbox Code Playgroud)

在这里,简单对象要经过几个类型的变化,从@Anno(2) Object@Anno(1) Object@Anno(4) Object@Anno(3) Object并在此代码相同的对象,甚至是由两个举行的结尾不同类型的变量,@Anno(1) Object@Anno(3) Object在同一时间!

您可以使用审计工具来验证这些类型转换对于语义@Anno所暗示的是否合法,但对于Java语言本身而言,它们没有任何意义并且将始终被接受.并且在运行时,实例的类型将始终Object不受类型注释的影响.

Reflection API提供了查询类和成员声明的注释类型的方法,其中包括方法的参数和返回类型,但是您无法查询new表达式的类型注释,因为您将无法确定方法是否实际包含new表达式,更不用说键入应用于该new表达式的注释.

可能有第三方库在字节代码处理库上安排,它们将在运行时提供对这些注释的访问...

  • 类型注释的设计中心可以对程序进行更好的静态分析.这些注释可以反射地用于反射所涵盖的Java程序部分 - 类和成员声明.但是反思并没有深入到Java表达式的水平 - 而且很可能永远都不会.而且,即使他们这样做了,这仍然无济于事(考虑一下如何实现这一点,以及它会带来的成本.) (4认同)