Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
1.Annotation 的作用
1.1.编译检查
Annotation 具有"让编译器进行编译检查的作用"。
例如,@SuppressWarnings, @Deprecated 和 @Override 都具有编译检查作用。
1.2.在反射中使用
在反射的 Class, Method, Field 等函数中,有许多于 Annotation 相关的接口。
这也意味着,我们可以在反射中解析并使用 Annotation。框架中较多使用,如SpringBoot。
1.3.生成帮助文档
通过给 Annotation 注解加上 @Documented 标签,能使该 Annotation 标签出现在 javadoc 中。
2.Annotation 的架构
java Annotation 的组成中,有 3 个非常重要的主干类。它们分别是:
2.1.Annotation.java
注释的抽象接口,定义了注释应具有的属性或功能。补充,现在很多框架对于概念的抽线多用接口,而不是类,如Camunda。
package java.lang.annotation;
public interface Annotation {
boolean equals(Object obj);
int hashCode();
String toString();
Class<? extends Annotation> annotationType();
}
2.2.ElementType.java
ElementType 规定了注解可以放置的位置
package java.lang.annotation;
public enum ElementType {
TYPE, /* 类、接口(包括注释类型)或枚举声明 */
FIELD, /* 字段声明(包括枚举常量) */
METHOD, /* 方法声明 */
PARAMETER, /* 参数声明 */
CONSTRUCTOR, /* 构造方法声明 */
LOCAL_VARIABLE, /* 局部变量声明 */
ANNOTATION_TYPE, /* 注释类型声明 */
PACKAGE /* 包声明 */
}
2.3.RetentionPolicy.java
RetentionPolicy 规定了注解的生命周期
package java.lang.annotation;
public enum RetentionPolicy {
SOURCE, /* Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该Annotation信息了 */
CLASS, /* 编译器将Annotation存储于类对应的.class文件中。默认行为 */
RUNTIME /* 编译器将Annotation存储于class文件中,并且可由JVM读入 */
}
3.jdk自带注解
@Retention -- @Retention只能被用来标注“Annotation类型”,而且它被用来指定Annotation的RetentionPolicy属性。
@Target -- @Target只能被用来标注“Annotation类型”,而且它被用来指定Annotation的ElementType属性。
@Inherited -- @Inherited只能被用来标注“Annotation类型”,它所标注的Annotation具有继承性。
@Deprecated -- @Deprecated 所标注内容,不再被建议使用。
@Override -- @Override 只能标注方法,表示该方法覆盖父类中的方法。
@Documented -- @Documented 所标注内容,可以出现在javadoc中。
@SuppressWarnings -- @SuppressWarnings 所标注内容产生的警告,编译器会对这些警告保持静默。
3.1.@Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}
说明:
(01) @interface – 它的用来修饰 Inherited,意味着 Inherited 实现了 java.lang.annotation.Annotation 接口;即 Inherited 就是一个注解。
(02) @Documented – 它的作用是说明该注解能出现在 javadoc 中。
(03) @Retention(RetentionPolicy.RUNTIME) – 它的作用是指定 Inherited 的策略是 RetentionPolicy.RUNTIME。这就意味着,编译器会将 Inherited 的信息保留在 .class 文件中,并且能被虚拟机读取。
(04) @Target(ElementType.ANNOTATION_TYPE) – 它的作用是指定 Inherited 的类型是 ANNOTATION_TYPE。这就意味着,@Inherited 只能被用来标注 “Annotation 类型”。
(05) @Inherited 的含义是,它所标注的Annotation将具有继承性,及被它标注的类的子类继承(也具有)该注解。
3.2.@Target
前面我们说过,ElementType 是 Annotation 的类型属性。而 @Target 的作用,就是来指定 Annotation 的类型属性。
@Target(ElementType.TYPE) 的意思就是指定该 Annotation 的类型是 ElementType.TYPE。这就意味着,该注解是来修饰"类、接口(包括注释类型)或枚举声明"的注解。
定义 Annotation 时,@Target 可有可无。若有 @Target,则该 Annotation 只能用于它所指定的地方;若没有 @Target,则该 Annotation 可以用于任何地方。
3.3.@Retention
前面我们说过,RetentionPolicy 是 Annotation 的策略属性,而 @Retention 的作用,就是指定 Annotation 的策略属性。
@Retention(RetentionPolicy.RUNTIME) 的意思就是指定该 Annotation 的策略是 RetentionPolicy.RUNTIME。这就意味着,编译器会将该 Annotation 信息保留在 .class 文件中,并且能被虚拟机读取。
定义 Annotation 时,@Retention 可有可无。若没有 @Retention,则默认是 RetentionPolicy.CLASS。