关于实例创建的Java 8注释

时间:2014-08-14 19:04:09

标签: java reflection annotations java-8

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

new @Interned MyObject();

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

1 个答案:

答案 0 :(得分:6)

应用于像new @Anno Object()这样的实例创建的注释是不是创建对象的属性,而只是new表达式的(编译时)类型。在运行时,对象的实际类型没有注释,就像它没有您在创建实例时指定的通用类型参数一样。

请考虑以下示例:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
@interface Anno { int value(); }

...

@Anno(1) Object o=new @Anno(2) Object();
@Anno(3) Object p=(@Anno(4) Object)o;

此处,简单对象经历了多种类型更改,从@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表达式的注释。

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