ITEEDU

Meta-Annotation

Annotation 类型可以被它们自己所标注。Java5.0定义了4个标准的meta-annotation类型,它们被用来提供对其它annotation类型作说明。这些类型和它们所支持的类在java.lang.annotation包中可以找到。如果需要更详细的信息可以参考jdk5.0手册。

1.再谈Target

作为meta-annotation类型的Target,它描述了annotation所修饰的程序成员的类型。当一个annotation类型没有 Target时,它将被作为普通的annotation看待。当将它修饰一个特定的程序成员时,它将发挥其应用的作用,例如:Override用于修饰方法时,增加了@Target这个meta-annotation就使编译器对annotation作检查,从而去掉修饰错误类型的Override。

Target meta-annotation类型有唯一的value作为成员。这个成员的类型是java.lang.annotation.ElementType[]类型的,ElementType类型是可以被标注的程序成员的枚举类型。

2.Retention的用法

我们在文章的开头曾经提到过Retention,但是没有详细讲解。Retention描述了annotation是否被编译器丢弃或者保留在class文件;如果保留在class文件中,是否在class文件被装载时被虚拟机读取。默认情况下,annotation被保存在class文件中,但在运行时并不能被反射访问。Retention具有三个取值:source、class、runtime,这些取值来自 java.lang.annotation.RetentionPolicy的枚举类型值。

Retention meta-annotation类型有唯一的value作为成员,它的取值来自java.lang.annotation.RetentionPolicy的枚举类型值。

3.Documented

Documented是一个meta-annotation类型,用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。

Documented是一个marker annotation,没有成员。

4.Inherited

@Inherited meta-annotation也是一个marker annotation,它阐述了某个被标注的类型是被继承的。如果一个使用了@Inherited修饰的annotation类型被用于一个class,则这个annotation将被用于该class的子类。

注意:@Inherited annotation类型是被标注过的class的子类所继承。类并不从它所实现的接口继承annotation,方法并不从它所重载的方法继承annotation。

值得思考的是,当@Inherited annotation类型标注的annotation的Retention是RetentionPolicy.RUNTIME,则反射API增强了这种继承性。如果我们使用java.lang.reflect去查询一个@Inherited annotation类型的annotation时,反射代码检查将展开工作:检查class和其父类,直到发现指定的annotation类型被发现,或者到达类继承结构的顶层。