参考:https://blog.csdn.net/hongxue8888/article/details/90319473
Retention
在Annotation中,可以使用Retention定义一个Annotation的保存范围。Retention和RetentionPolicy定义如下:
package java.lang.annotation;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
/**
* Returns the retention policy.
* @return the retention policy
*/
RetentionPolicy value();
}
package java.lang.annotation;
/**
* Annotation retention policy. The constants of this enumerated type
* describe the various policies for retaining annotations. They are used
* in conjunction with the {@link Retention} meta-annotation type to specify
* how long annotations are to be retained.
*
* @author Joshua Bloch
* @since 1.5
*/
public enum RetentionPolicy {
/**
* 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
}
定义在RUNTIME范围有效的Annotation
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyRetentionAnnotation {
public String name() default "xiaoming";
}
RetentionPolicy的3个范围:
序号 | 范围 | 描述 |
---|---|---|
1 | SOURCE | 此Annotation类型的信息只会保留在程序源文件中(*.java),编译之后不会保存在编译好的类文件(*.class)中。 |
2 | CLASS | 此Annotation类型的信息会保留在程序源文件中(*.java)和编译好的类文件(*.class)中。在使用此类时,Annotation信息不会被加载到虚拟机(JVM)中,如果一个Annotation声明时没有指定范围,则默认是此范围。 |
3 | RUNTIME | 此Annotation类型的信息会保留在程序源文件中(*.java)、类文件(*.class)中。在执行时会加载到JVM中。 |
Target
如果一个Annotation没有明确地指明定义的位置,则可以在任意的位置使用,例如之前所讲解的全部的Annotation因为没有指定应用位置,所以可以在任意位置上进行定义,如下所示:
package target;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotationReflect {
public String key() default "XiaoMing";
public String value() default "小明";
}
@MyAnnotationReflect(key = "XiaoMing",value = "小明")//位置1
public class SimpleBean {
@MyAnnotationReflect(key = "XiaoMing",value = "小明")//位置2
public String toString() {
return "Hello XiaoMing";
}
}
如果希望一个自定义的Annotation只能在指定的位置上出现,例如只能在类上或者只能在方法上声明,则必须使用@Target注释。
@Target明确指出了一个Annotation的使用位置,此注释的定义如下:
package java.lang.annotation;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
ElementType[] value();
}
在@Target中存在一个ElementType[]枚举类型的变量,这个变量主要指定Annotation的使用限制。
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
如下表所示:
范围 | 描述 | |
---|---|---|
TYPE | Class, interface (including annotation type), or enum declaration | 只能用在类、接口、枚举类型上 |
FIELD | Field declaration (includes enum constants) | 只能用在字段的声明(包括枚举常量)上 |
METHOD | Method declaration | 只能用在方法的声明上 |
PARAMETER | Formal parameter declaration | 只能用在参数的声明上 |
CONSTRUCTOR | Constructor declaration | 只能用在构造方法的声明上 |
LOCAL_VARIABLE | Local variable declaration | 只能用在局部变量的声明上 |
ANNOTATION_TYPE | Annotation type declaration | 只能用在注释的声明上 |
PACKAGE | Package declaration | 只能用在包的声明上 |
TYPE_PARAMETER(@since 1.8) | Type parameter declaration | |
TYPE_USE(since 1.8) | Use of a type |