JDK 1.5 新特性学习笔记(4)

 5. Annotation(注解)java

Annotation是一种元数据(metadata),即“Information about information”,在源代码中标记。数组

注解使用类Javadoc的语法,@ANNOTATION_NAME(参数),参数为KEY=VALUE的形式。ide

5.1 内置注解类型this

内置的注解类型位于java.lang包中,不需导入,开箱即用。spa

5.1.1. Overridecode

标明方法覆写了基类的方法。此注解为一种标识注解,无参数。orm

JDK源码以下:继承

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}

5.1.2. Deprecated接口

代表不推荐使用。此注解为一种标识注解,无参数。ip

JDK源码以下:

@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Deprecated {
}

5.1.3. SuppressWarnings

关闭类、方法、属性等的指定编译器警告。此注解接收一个String[]类型的参数。

JDK源码以下:

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}

SuppressWarnings注解用法示例:

@SuppressWarnings(value={"unchecked"})
public void nonGenericsMethod( ) {
    List list = new ArrayList( );
    list.add("foo");
}

5.2 注解的注解

注解的注解即描述元数据的元数据,如上述注解的JDK源代码中的注解。

5.2.1 Target

标明注解能够做用的目标范围。

JDK源码以下:

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

其中ElementType的取值为:

  • TYPE:类、接口(包含注解)、枚举类型

  • FIELD:属性(包含枚举类型的值)

  • METHOD:方法

  • PARAMETER:方法参数

  • CONSTRUCTOR:构造方法

  • LOCAL_VARIABLE:局部变量

  • ANNOTATION_TYPE:注解类型

  • PACKAGE:包

JDK源代码:

public enum ElementType {
    /** Class, interface (including annotation type), or enum declaration */
    TYPE,

    /** Field declaration (includes enum constants) */
    FIELD,

    /** Method declaration */
    METHOD,

    /** Parameter declaration */
    PARAMETER,

    /** Constructor declaration */
    CONSTRUCTOR,

    /** Local variable declaration */
    LOCAL_VARIABLE,

    /** Annotation type declaration */
    ANNOTATION_TYPE,

    /** Package declaration */
    PACKAGE
}

5.2.2 Retention

标明注解能够保持的范围。

JDK源码以下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Retention {
    RetentionPolicy value();
}

其中RetentionPolicy的取值为:

  • SOURCE:源代码,编译器自动忽略
  • CLASS:类,默认设置,编译器将其记录在class文件中,但虚拟机运行时不保留
  • RUNTIME:运行时,编译器将其记录在class文件中,虚拟机运行时将其保留,能够经过反射获取
JDK源码:
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
}

5.2.3 Documented

标明Javadoc文档中需包含此注解内容。

 JDK源码以下:

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

注:Documented注解的使用要求注解的RetentionPolicy的设置为RUNTIME

5.2.4 Inherited

标明做用于class上的注解是被自动继承的注解。

JDK源码以下:
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Inherited {
}

注意:

1. Inherited注解的使用要求注解的RetentionPolicy的设置为RUNTIME

2. 接口上的注解即便是标明了@Inherited的注解,也不会被继承

3. 基类方法上的注解若是标明了@Inherited则会被继承,但在被子类覆写后也会丢失注解信息

5.3 自定义注解类型

注解类型本质上是一种Java的接口,但使用@interface关键字进行声明。

示例:

public @interface Todo {
    public enum Severity {CRITICAL, IMPORTANT, TRIVIAL, DOCUMENTATION};
    String description();
    String assignedTo();
}

使用示例:

@Todo(
    severity=Todo.Severity.CRITICAL,
    description="Figure out the amount of order",
    assignedTo="Tom"
)
public void calculate() {
    // Need to finish this method later
}

5.5 新增的反射API

java.lang.reflect包中新增了AnnotatedElement接口,JDK源码以下:

public interface AnnotatedElement {
    boolean isAnnotationPresent(Class<? extends Annotation> annotationClass);
    <T extends Annotation> T getAnnotation(Class<T> annotationClass);
    Annotation[] getAnnotations();
    Annotation[] getDeclaredAnnotations();
}
  • isAnnotationPresent:判断是否标注了指定注解
  • getAnnotation:获取指定注解,没有则返回null
  • getAnnotations:获取全部注解,包括继承自基类的,没有则返回长度为0的数组
  • getDeclaredAnnotations:获取自身显式标明的全部注解,没有则返回长度为0的数组

reflect包中的相关类如Class等都实现了此接口。

注:反射要求注解的RetentionPolicy的设置为RUNTIME

相关文章
相关标签/搜索