定义
Annotation (注解) 是 Java 5 引入的新特性。提供了一种安全的类似注释的机制,将任何信息或者元数据(metadata) 与程序元素( 类、方法、成员变量等 ),关联起来。为程序元素 ( 类、方法、成员变量 )提供了更直观的注释说明,这些说明与业务逻辑无关,并提供给指定的框架或工具使用。Annotation 位于 java.lang.annotation 包下
原理
注解本质是一个继承了 Annotation 接口的特殊接口,接口的具体实现类是 Java 运行时生成的动态代理类。我们通过反射获取注解时,实际返回的是 Java 运行时生成的代理类对象 ($Proxy1) 。通过代理对象调用自定义注解(接口)的方法,会最终调用 AnnotationInvocationHandler 的 Invoke 方法。
分类
- 元注解 : 描述注解的注解
- 自定义注解 : 根据元注解,去自定义注解(@Override、@Service)
元注解
- @Target
@Target 注解用来指定一个注解的使用范围,表示该注解,可以用在什么地方。该注解有一个成员变量 value ,value 的声明类型是 ElementType 数组,这就表示一个注解可以同时指定多个 ElementType 类型。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
* 用于类型参数 1.8 新增
*/
TYPE_PARAMETER,
/**
* Use of a type * * @since 1.8
* 用于类型使用 1.8 新增
*/
TYPE_USE,
/**
* Module declaration. * * @since 9
* 用于模块 1.9 新增
*/
MODULE
}
- @Documentd
使用 @Documentd 注解修饰的注解,会被 JavaDoc 工具提取成文档 - @Retention
@Retention 注解用于描述注解的保留策略,表示在什么级别保存该注解信息。该注解有一个变量 value,value 的声明类型是 RetentionPolicy ,RetentionPolicy 是一个枚举类,枚举如下
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 文件中,但是运行时不会被虚拟机保留,这是所有注解的默认保留策略
*/
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
编译器将注解记录在 class 文件中,而且运行时也会被虚拟机保留,因此可以以反射的方式读取它们
*/
RUNTIME
}
- @Inherited
@Inherited 注解用来指定该注解可以继承。@Inherited 注解只会影响类上的注解,而方法和属性等上面的注解的继承性不受 @Inherited 注解的影响。而且声明在方法、成员变量等处的注解,即使该注解没有使用 @Inherited 注解,那么默认也是可以继承的,除非子类重写了父类的方法或者覆盖了父类的成员变量。 - @Repeatable
@Repeatable 注解是 Java 8 新增的一个元注解,用该注解来标识一个注解在一个元素上使用多次。
自定义注解
- 都是由上面的元注解,组合出来的,比如 @Target @Retention @Documentd
注解的使用
- 注解组合使用
- 注解不能继承其他类和实现其他接口,只能组合使用
- 注解与反射结合使用