Annotation 源码分析

  • JDK5.0 引入,可以通过反射机制动态获取,大量应用于java框架中
  • 内置注解
  • @Override
  • 重写父类方法时
@Target(ElementType.METHOD)  //该注解只能作用于方法
@Retention(RetentionPolicy.SOURCE)  //在编译时起作用,静态检查
public @interface Override {
    
}
  • @Deprecated
  • 使用它存在风险,可能导致错误
  • 可能在未来版本中不兼容
  • 可能在未来版本中删除
  • 一个更好和更高效的方案已经取代它
@Documented  //表明可以生成为javadoc文档
@Retention(RetentionPolicy.RUNTIME)  //在运行时起作用
//可以作用于构造函数,属性,局部变量,方法,包,模块,参数,类型上
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, MODULE, PARAMETER, TYPE})
public @interface Deprecated {
    /**
     * Returns the version in which the annotated element became deprecated.
     * The version string is in the same format and namespace as the value of
     * the {@code @since} javadoc tag. The default value is the empty
     * string.
     *
     * @return the version string
     * @since 9
     */
    String since() default "";  //一个属性since  String类型,默认为空

    /**
     * Indicates whether the annotated element is subject to removal in a
     * future version. The default value is {@code false}.
     *
     * @return whether the element is subject to removal
     * @since 9
     */
    boolean forRemoval() default false;  //是否已删除
}
  • @SuppressWarnings
  • 告诉编译器忽略指定的警告,不用在编译完成后出现警告信息。
//可以做用于类型,属性,方法,参数,构造函数,局部变量,模块
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, MODULE})
//作用于编译期
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    /**
     * The set of warnings that are to be suppressed by the compiler in the
     * annotated element.  Duplicate names are permitted.  The second and
     * successive occurrences of a name are ignored.  The presence of
     * unrecognized warning names is <i>not</i> an error: Compilers must
     * ignore any warning names they do not recognize.  They are, however,
     * free to emit a warning if an annotation contains an unrecognized
     * warning name.
     *
     * <p> The string {@code "unchecked"} is used to suppress
     * unchecked warnings. Compiler vendors should document the
     * additional warning names they support in conjunction with this
     * annotation type. They are encouraged to cooperate to ensure
     * that the same names work across multiple compilers.
     * @return the set of warnings to be suppressed
     */
    String[] value(); //String类型数组 写为value时在写注解时可以省略value= 
}


value常见取值:
    all, to suppress all warnings抑制所有警告
    boxing, to suppress warnings relative to boxing/unboxing operations抑制与装箱/拆箱操作相关的警告
    cast, to suppress warnings relative to cast operations抑制与转换操作相关的警告
    dep-ann, to suppress warnings relative to deprecated annotation抑制与弃用注释相关的警告
    deprecation, to suppress warnings relative to deprecation抑制与弃用相关的警告
    fallthrough, to suppress warnings relative to missing breaks in switch statements抑制与 switch 语句中缺少中断相关的警告
    finally, to suppress warnings relative to finally block that don’t return抑制相对于 finally 块不返回的警告
    hiding, to suppress warnings relative to locals that hide variable抑制与隐藏变量的局部变量相关的警告
    incomplete-switch, to suppress warnings relative to missing entries in a switch statement (enum case)抑制与 switch 语句中缺失条目相关的警告(枚举大小写)
    nls, to suppress warnings relative to non-nls string literals抑制与非 nls 字符串文字相关的警告
    null, to suppress warnings relative to null analysis抑制与空分析相关的警告
    rawtypes, to suppress warnings relative to un-specific types when using generics on class params 在类参数上使用泛型时抑制与非特定类型相关的警告
    restriction, to suppress warnings relative to usage of discouraged or forbidden references抑制与使用不鼓励或禁止的引用有关的警告
    serial, to suppress warnings relative to missing serialVersionUID field for a serializable class抑制与可序列化类的缺少 serialVersionUID 字段相关的警告
    static-access, to suppress warnings relative to incorrect static access抑制与不正确的静态访问相关的警告
    synthetic-access, to suppress warnings relative to unoptimized access from inner classes抑制与来自内部类的未优化访问相关的警告
    unchecked, to suppress warnings relative to unchecked operations抑制与未经检查的操作相关的警告
    unqualified-field-access, to suppress warnings relative to field access unqualified抑制与不合格的字段访问相关的警告
    unused, to suppress warnings relative to unused code抑制与未使用代码相关的警告
  • 元注解:修饰注解的注解
  • 首先解释两个枚举类 1.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
     */
    TYPE_PARAMETER,

    /**
     * Use of a type
     *
     * @since 1.8
     */
    TYPE_USE,

    /**
     * Module declaration.
     *
     * @since 9
     */
    MODULE
}
  • 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,

    /**
     * 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
     */
    RUNTIME
}
  • @Target
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Target {
    /**
     * Returns an array of the kinds of elements an annotation type
     * can be applied to.
     * @return an array of the kinds of elements an annotation type
     * can be applied to
     */
    ElementType[] value();  //枚举类ElementType数组,表明注解可以作用于多个位置
}
  • @Retention
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    /**
     * Returns the retention policy.
     * @return the retention policy
     */
    RetentionPolicy value(); //指明注解的作用生命周期,单个枚举类 RetentionPolicy
}
  • @Documented
  • 默认情况下,javadoc是不包括注解的. 但如果声明注解时指定了 @Documented,则它会被 javadoc 之类的工具处理, 所以注解类型信息也会被包括在生成的文档中,是一个标记注解,没有成员。
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
    //为空
}
  • @Inherited
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
    //为空
}

自定义注解并通过反射获取信息

  • @TableName 表明实体类与哪个数据库表对应
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
    String value() default "";
}
//在实体类上使用自定义注解
@TableName("cat")
public class Cat {
    private int age;
    private String name;
    public static void main(String[] args) throws ClassNotFoundException {
        //通过一种获取Class对象的方式 forName
        Class<?> c1 = Class.forName("org.yrdm.ch1.Cat");
        //获取所有注解并打印
        Annotation[] annotations = c1.getDeclaredAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
		//获取特定注解并输出value值
        TableName anno = c1.getDeclaredAnnotation(TableName.class);
        String value = anno.value();
        System.out.println(value);
    }
}

运行结果:
    @org.yrdm.ch1.TableName(value="cat")
	cat