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

相關文章
相關標籤/搜索