- 注解 是源代码的元数据(给程序元素提供元数据支持)。
- 注解本身不影响程序逻辑,但注解可以被编译或运行。
- 如果一个注解中有一个名称为value的属性(名字必须为value),且你只想设置value属性(即其他属性都采用默认值或者你只有一个value属性),那么可以省略掉“value=”部分。
- 注解的关键字 @interface + 元注解 完成注解的定义
- 注解本质上实现的是 java.lang.annotation.Annotation 接口, 也就是Annotation接口是所有注解的父接口。
- 带成员变量的注解的定义,以无形参的方法形式来声明Annotation的成员变量,方法名和返回值定义了成员变量名称和类型。使用default关键字设置初始值。没有设置初始值的变量则使用时必须提供,有初始值的变量可以设置也可以不设置。
- 元注解,修饰注解的注解
- @Retention (保留)
- RetentionPolicy.SOURCE 编译器使用后,直接丢弃这种策略的注解
- RetentionPolicy.CLASS 默认值,字节码文件中存在,当程序运行时,JVM不会保留该注解
- RetentionPolicy.RUNTIME 保存在字节码中,JVM运行时会保留,程序可以通过反射获取该注解
- @Target 注解可以使用的位置
- ElementType.TYPE //Class, interface (including annotation type), or enum declaration
- ElementType.FIELD //Field declaration (includes enum constants)
- ElementType.METHOD //方法上
- ElementType.PARAMETER //形参
- ElementType.CONSTRUCTOR // 构造器
- ElementType.LOCAL_VARIABLE // 本地变量 、局部变量
- ElementType.ANNOTATION_TYPE // 指定该该策略的Annotation只能修饰Annotation.
- ElementType.PACKAGE // 包
- ElementType.TYPE_PARAMETER //类型参数声明
- ElementType.TYPE_USE // Java8新增 Type Annotation可用在任何用到类型的地方。
- JDK5开始,Java增加了对元数据(MetaData)的支持,即注解。
- JDK1.7 之前访问和处理Annotation的工具统称APT(Annotation Processing Tool)(JDK1.7 后就被废除了),JDK1.7 及之后采用了JSR 269 API。
- JDK 1.6 的tools.jar中提供了编写注解处理器的API, 同时1.6在 javax.annotation.processing and javax.lang.model包下新增了JSR269的API。 1.6两种方式并存。
- RetentionPolicy.SOURCE 表示注解在源码中,这种注解的处理:通过继承JDK 1.6提供的javax.annotation.processing.AbstractProcessor,自定义注解处理器,在使用该注解的类编译的时候执行重写的方法process 来在编译器拓展功能。
- RetentionPolicy.CLASS 在字节码中,这种注解我猜想要用类似ASM的类库去操作拓展功能。
- RetentionPolicy.RUNTIME 在运行的时候,通过反射获取注解信息,拓展功能。
- Java8 新增重复注解。
- @Repeatable(DupMyTag.class) public @interface MyTag{}
- public @interface DupMyTag { MyTag[] value();}
- Java8 新增的Type Annotation注解
- @Target(TYPE_USE)修饰的注解称为Type Annotation(类型注解),Type Annotation可用在任何用到类型的地方。
- 编译时处理Annotation, APT JSR 269
- 只有定义Annotation时使用了@Rentention(RetentionPolicy.RUNTIME)修饰,该Annotation才会在运行时可见,JVM才会在装载.class文件时读取保存在class文件中的Annotation。只有RetentionPolicy.RUNTIME 修饰的注解,反射才可以获取注解信息。
- java.lang.reflect.AnnotatedElement 接口代表程序中可以接受注解的程序元素。即所有可以接受注解的程序元素都会实现该接口。Class Constructor Field Method Package等实现了该接口,因此可以通过反射获取注解信息。