在阅读spring源码时,总能看见各种利用注解反射机制来写的代码,我顺便回去复习了一下反射与注解。
元注解
先来看看annotation包下的结构
一共定义了6个注解:
-
@Document
-
@Target
-
@Retention
-
@Inherited
-
@Native
-
@Repeatable
其中前四个称为元注解,他们的作用就是负责注解其他注解,被用来提供对其他annotation类型的说明。
注解的定义
-
@Target 标识注解的使用范围,可以赋值为
ElementType
类型,ElementType
类型继承枚举类(默认继承),它在JDK11的定义如下:public enum ElementType { TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE, TYPE_PARAMETER, TYPE_USE, MODULE; private ElementType() { } }
-
@Retention
定义:被它所注解的注解保留多久
可以赋值
RetentionPolicy
类型,RetentionPolicy
在JDK11的定义如下:public enum RetentionPolicy { SOURCE, CLASS, RUNTIME; private RetentionPolicy() { } }
SOURCE : 表明注解会被编译器丢弃,字节码中不会带有注解信息 ( 注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略 )
CLASS: 表明注解会被写入字节码文件,且是@Retention
的默认值 ( 注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期 )
RUNTIME : 表明注解会被写入字节码文件,并且能够被JVM 在运行时获取到,可以通过反射的方式解析到
( 注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在 )
-
@Documented
@Document
注解用途主要是标识类型是否要被收入javadoc
什么意思呢,举个例子:如果一个注解@A,被@Documented标注,那么被@A修饰的类,生成文档时,会显示@A。如果@A没有被@Documented标准,最终生成的文档中就不会显示@A。
-
@Inherited
如果一个超类被
@Inherited
注解过的注解进行注解的话,那么如果它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解。举个例子
@Inherited @Retention(RetentionPolicy.RUNTIME) @interface Test {} @Test public class A {} public class B extends A {}
B继承A,其中@Test这个注解被
@Inherited
注解, 之后类 A 被 Test 注解,类 B 继承 A,类 B 也拥有 Test 这个注解。