@Retention
确定Annotation被保存的生命周期, 需要接收一个Enum对象RetentionPolicy作为参数。 publicenumRetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/ SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/ CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/ RUNTIME
} @Documented 文档化 @Target
表示该Annotation可以修饰的范围,接收一个Enum对象EnumType的数组作为参数。 publicenumElementType {
/** Class, interface (including annotation type), or enum declaration */ TYPE,
/** Field declaration (includes enum constants) */ FIELD,
/** Method declaration */ METHOD,
/** Parameter declaration */ PARAMETER,
/** Constructor declaration */ CONSTRUCTOR,
/** Local variable declaration */ LOCAL_VARIABLE,
/** Annotation type declaration */ ANNOTATION_TYPE,
当Java源代码被编译时,编译器的一个插件annotation处理器则会处理这些annotation。处理器可以产生报告信息,或者创建附加的Java源文件或资源。如果annotation本身被加上了RententionPolicy的运行时类,则Java编译器则会将annotation的元数据存储到class文件中。然后,Java虚拟机或其他的程序可以查找这些元数据并做相应的处理。
当然除了annotation处理器可以处理annotation外,我们也可以使用反射自己来处理annotation。Java SE 5有一个名为AnnotatedElement的接口,Java的反射对象类Class,Constructor,Field,Method以及Package都实现了这个接口。这个接口用来表示当前运行在Java虚拟机中的被加上了annotation的程序元素。通过这个接口可以使用反射读取annotation。AnnotatedElement接口可以访问被加上RUNTIME标记的annotation,相应的方法有getAnnotation,getAnnotations,isAnnotationPresent。由于Annotation类型被编译和存储在二进制文件中就像class一样,所以可以像查询普通的Java对象一样查询这些方法返回的Annotation。