Java-元注解

  如果某注解类A注解的对象也是一个注解类,那么注解类A即是一个元注解。

@Retention:定义注解的保留策略

package java.lang.annotation;

@Documented
// 注解会被一直保留,包括虚拟机运行期间 @Retention(RetentionPolicy.RUNTIME) // 表明该注解类可以注解其他的注解类 // 当前注解类是元注解类 @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { /** * @return 注解的保留策略/注解的生命周期 */ RetentionPolicy value(); }

  注解的保留策略全部定义在枚举类RetentionPolicy中。

package java.lang.annotation;

// 注解的声明周期
public enum RetentionPolicy {
    /**
     * 注解仅保留在源码中,在java文件被编译成class文件的期间被丢弃。
     */
    SOURCE,

    /**
     * 注解仅保留在源码和class文件中,在class文件被加载到jvm的时候被丢弃。
     */
    CLASS,

    /**
     * 注解始终保留,代码运行期间可以通过反射来读取到该级别的注解。
     */
    RUNTIME
}

@Target:定义注解类注解的目标类型

package java.lang.annotation;

@Documented
// 注解会被一直保留,包括虚拟机运行期间
@Retention(RetentionPolicy.RUNTIME)
// 表明该注解类可以注解其他的注解类
// 当前注解类是元注解类
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * 返回该注解能注解的元素类型数组
     */
    ElementType[] value();
}

  注解的目标类型全部定义在枚举类ElementType中。

package java.lang.annotation;

public enum ElementType {
    // 可注解的目标类型:类、接口(包括注解)、枚举类
    TYPE,

    // 可注解的目标类型:成员变量、枚举类常量
    FIELD,

    // 可注解的目标类型:方法
    METHOD,

    // 可注解的目标类型:方法参数
    PARAMETER,

    // 可注解的目标类型:构造函数
    CONSTRUCTOR,

    // 可注解的目标类型:本地变量
    LOCAL_VARIABLE,

    // 可注解的目标类型:注解
    ANNOTATION_TYPE,

    // 可注解的目标类型:包
    // 注解包的代码是写在package-info.java文件中,
    // 一般需要手动创建,该文件存放在被注解的包路径下。
    PACKAGE,

    /**
     * 可注解的目标类型:类型参数/泛型参数
     * @since 1.8
     */
    TYPE_PARAMETER,

    /**
     * 可注解所有类型的目标
     * @since 1.8
     */
    TYPE_USE
 }   

@Document:说明在生成javadoc时将保留该注解

package java.lang.annotation;

@Documented
// 表明该注解将会一直保留至虚拟机整个运行期间 @Retention(RetentionPolicy.RUNTIME) // 可以注解在注解元素上,标明这是一个元注解 @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { }

@Inherited:定义子类可以从父类继承的注解

package java.lang.annotation;

@Documented
// 注解会被一直保留,包括虚拟机运行期间
@Retention(RetentionPolicy.RUNTIME)
// 表明该注解类可以注解其他的注解类
// 当前注解类是元注解类
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

  @Inherited是元注解,注解的目标是注解,当然也包括元注解,但是什么意义都没有,纯属脱裤子放屁。

  假设存在一个被@Inherited注解的注解InheritedAnnotation:

InheritedAnnotation注解的对象

子类(或子类的方法)是否能继承父类(或父类的方法)

接口InterfaceB

不能

类ClassA

类ClassA中的一个方法FunctionA

子类只要不复写方法FunctionA,子类就可以继承父类方法上的注解

接口InterfaceB中的一个抽象方法FunctionB

实现接口的子类必然要复写方法,因此不能

@Repeatable:定义可多次注解同一目标的注解类

  一般情况下,使用一个注解类A来注解目标E,注解类A只能注解一次目标E。如果需要注解类A对目标E注解多次,那么可以就可以使用@Repeatable来注解A。

package java.lang.annotation;

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Repeatable {
    /**
     * 注解容器:容器中存放的元素也是注解
     * @return 注解类型容器
     */
    Class<? extends Annotation> value();
}

示例:使用@Person多次注解Man类

@Target(ElementType.TYPE)  
@Retention(RetentionPolicy.RUNTIME)
public @interface Persons {
    Person[] value();
}

@Repeatable(Persons.class)
public @interface Person{
    String role() default "";
}

@Person(role="CEO")
@Person(role="husband")
@Person(role="father")
@Person(role="son")
public class Man {
    String name="";
}

猜你喜欢

转载自www.cnblogs.com/517cn/p/10872049.html