深入学习JAVA注解-Annotation(学习过程) (2)

@Target -用于指明被修饰的注解最终可以作用的目标是谁,也就是指明,你的注解到底是用来修饰方法的?修饰类的?还是用来修饰字段属性的。Target 的定义如下:

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { /** * Returns an array of the kinds of elements an annotation type * can be applied to. * @return an array of the kinds of elements an annotation type * can be applied to */ ElementType[] value(); }

我们可以通过以下的方式来为这个 value 传值:

@Target(value = {ElementType.FIELD})

被这个 @Target 注解修饰的注解将只能作用在成员字段上,不能用于修饰方法或者类。其中,ElementType 是一个枚举类型,有以下一些值:

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 } 注意:上述中文翻译为自己翻译的,如果有错误,请自行查阅官方文档 最后从jdk1.8添加的两个枚举类型的作用,是通过搜索网络资料查询得来 类型注解: JDK1.8之后,关于元注解@Target的参数类型ElementType枚举值多了两个: TYPE_PARAMETER和TYPE_USE。 在Java8之前,注解只能是在声明的地方所使用,Java8开始,注解可以应用在任何地方。 ElementType.TYPE_PARAMETER 表示该注解能写在类型变量的声明语句中(如:泛型声明)。 ElementType.TYPE_USE 表示该注解能写在使用类型的任何语句中。

@Retention - 标识这个注解怎么保存,是只在代码中,还是编入class文件中,或者是在运行时可以通过反射访问。它的基本定义如下:

@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { /** * Returns the retention policy. * @return the retention policy */ RetentionPolicy value(); }

同样的,它也有一个 value 属性:

@Retention(value = RetentionPolicy.RUNTIME

这里的 RetentionPolicy 依然是一个枚举类型,它有以下几个枚举值可取:

public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, //当前注解编译期可见,不会写入 class 文件 /** * 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, //类加载阶段丢弃,会写入 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 //永久保存,可以反射获取 }

@Retention 注解指定了被修饰的注解的生命周期,一种是只能在编译期可见,编译后会被丢弃,一种会被编译器编译进class文件中,无论是类或是方法,乃至字段,他们都是有属性表的,而 JAVA 虚拟机也定义了几种注解属性表用于存储注解信息,但是这种可见性不能带到方法区,类加载时会予以丢弃,最后一种则是永久存在的可见性。

如何验证生命周期? @Target(ElementType.TYPE) @Retention(RetentionPolicy.CLASS) public @interface TestAnnotation { } @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) public @interface TestAnnotation2 { } @Target(ElementType.TYPE) @Retention(RetentionPolicy.SOURCE) public @interface TestAnnotation3 { } @TestAnnotation @TestAnnotation2 @TestAnnotation3 public class TestJava { public static void main(String[] args) throws ClassNotFoundException { Class<?> testJava = Class.forName("com.sinosoft.lis.pubfun.TestJava"); Annotation[] annotations = testJava.getAnnotations(); for (Annotation annotation : annotations) { System.out.println(annotation.annotationType()); } }

你明白我的意思吧。

@Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类).

@Documented - 标记这些注解是否包含在用户文档中.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspfwg.html