元注解就是可以注解到别的注解(组合注解)上的注解
一个注解准确意义上来说,只不过是一种特殊的注释而已,如果没有解析它的代码,它可能连注释都不如。
注解相对与XML有更大的便携性,易于维护修改。但XML的解耦性更好。

四种元注解

1. @Target(目标)

Target注解用来说明那些被它所注解的注解类可修饰的对象范围:

@Documented  
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.ANNOTATION_TYPE)  
public @interface Target {  
    ElementType[] value();  
}  

取值范围定义在枚举类 ElementType中

public enum ElementType { 
    TYPE, // 类、接口、枚举类 
    FIELD, // 成员变量(包括:枚举常量) 
    METHOD, // 成员方法 
    PARAMETER, // 方法参数 
    CONSTRUCTOR, // 构造方法 
    LOCAL_VARIABLE, // 局部变量 
    ANNOTATION_TYPE, // 注解类 
    PACKAGE, // 可用于修饰:包 
    TYPE_PARAMETER, // 类型参数,JDK 1.8 新增 
    TYPE_USE // 使用类型的任何地方,JDK 1.8 新增 
}

@Retention(保留)

描述被注解的注解,在它所修饰的类中可以被保留到何时

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

生命周期定义在枚举类 RetentionPolicy 中

public enum RetentionPolicy {
    SOURCE,    // 源文件保留
    CLASS,       // 编译期保留,默认值
    RUNTIME   // 运行期保留,可通过反射去获取注解信息
}

注解的保留时间,关系到注解可以在什么时候被用到(被解析)
如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解。
如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解。
如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,则可选用 SOURCE 注解

@Documented(记录)

添加注解后,生成的javadoc帮助文档上会保留注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}

这是一个纯粹的元注解,他没有属性~

@Inherited(遗传)

如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

这也是一个纯粹的注解,最熟悉的大概就是事务注解了

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional

他就是一个遗传性的注解