Java 註解介紹

baiiu發表於2017-03-16

前言

Java註解介紹

1. 註解中最重要的三個類

AnnotationElementTypeRetentionPolicy這三個類是註解中最重要的類,沒有這三個類就沒有註解,其中Annotation是介面,其餘兩個是列舉。
所有的註解都基於這三個類,所謂的元註解也是用這三個類生成的,只不過可修飾的元素(ElementType)為ANNOTATION_TYPE罷了,你也可以寫個元註解。

1. Annotation

package java.lang.annotation; //java.lang.annotation包下
public interface Annotation {
    boolean equals(Object var1);

    int hashCode();

    String toString();

    Class<? extends Annotation> annotationType();
}複製程式碼

2. ElementType

package java.lang.annotation; //java.lang.annotation包下
public enum ElementType {
    TYPE,  // 類、介面(包括註釋型別)或列舉宣告
    FIELD,  // 欄位宣告(包括列舉常量)
    METHOD,  //方法宣告
    PARAMETER,  //引數宣告
    CONSTRUCTOR,  //構造方法宣告
    LOCAL_VARIABLE,  //區域性變數宣告
    ANNOTATION_TYPE,  //註解型別宣告
    PACKAGE,  //包宣告
    TYPE_PARAMETER,  //型別引數宣告(1.8新加入),表示這個註解可以用來標註型別引數
    TYPE_USE; //型別使用宣告(1.8新加入),用於標註各種型別,只要是型別名稱,都可以進行註解

    private ElementType() {
    }
}複製程式碼

3. RetentionPolicy

package java.lang.annotation;//java.lang.annotation包下
public enum RetentionPolicy {
    SOURCE,  //註解將被編譯器丟棄;Annotation資訊僅存在於編譯器處理期間,編譯器處理完之後就沒有該Annotation資訊了
    CLASS,  //註解在class檔案中可用,但會被VM丟棄
    RUNTIME;  //VM將在執行期也保留註解資訊,因此可以通過反射機制讀取註解的資訊

    private RetentionPolicy() {
    }
}複製程式碼

2. 四種元註解

Java提供了四種元註解(meta-annotation),元註解就是專職負責註解其他的註解,所以這四種註解的Target值都是ElementType.ANNOTATION_TYPE

1. @Target
表示該註解可以用在什麼地方,由ElementType列舉定義

@Documented
@Retention(RetentionPolicy.RUNTIME) //被VM識別
@Target({ElementType.ANNOTATION_TYPE}) //修飾註解型別
public @interface Target {
    ElementType[] value(); //當使用此註解時,無預設註解,必須要傳入ElementType
}複製程式碼

2. @Retention
表示需要在什麼級別儲存該註解資訊,由RetentionPolicy列舉定義

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Retention {
    RetentionPolicy value(); // 必須要傳入
}複製程式碼

3. @Documented
表示註解會被包含在javaapi文件中

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Documented {
}複製程式碼

4. @Inherited
允許子類繼承父類的註解,即它所標註的Annotation將具有繼承性

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.ANNOTATION_TYPE})
public @interface Inherited {
}複製程式碼

3. 註解的基本語法

  //@Target(ElementType.Method)  
  //@Retention(RetentionPolicy.RUNTIME)
  public @interface MyAnnotation {
     int id(); // default 1; 不新增default值使用該註解時必須要傳入傳入
     String value() default ""; //如果只有value()這一個屬性需要賦值的話,可以省略鍵值對傳值
     // Integer id() default 1; //丟擲異常,Invalid type
  }複製程式碼
  1. @interface表示該類是一個註解,並實現了Annotation介面

  2. @Target表示該註解可以修飾的型別;如果不填,則此註解可以使用任何元素之上;

  3. @Retention用來定義註解在哪一個級別可用,是原始碼中可見、編譯器可見還是VM可見;如果不填,預設級別是CLASS。

  4. 註解元素可用的型別
    所有基本型別(int,float,boolean,byte,double,char,long,short)、 String、Class、enum、Annotation和以上型別的陣列;其它的值都會丟擲Error: 註釋值不是允許的型別

  5. 註解的快捷方式
    當註解內元素方法名為value()時,並且該元素是唯一一個需要賦值的值(另外的值有預設值),可以不用使用鍵值對來傳值,直接使用@MyAnnotation("2")傳值;如果有兩個,則要使用@MyAnnotation(id=1,value = "2")來傳值。

其中根據註解引數的個數,我們可以將註解分為:標記註解、單值註解、完整註解三類。

4. Java常用的註解

1. @Deprecated
標記註解,所標註內容,不再被建議使用。

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.METHOD, ElementType.PACKAGE, ElementType.PARAMETER, ElementType.TYPE})
public @interface Deprecated {
}複製程式碼

2. @Override
標記註解,只能標註方法,表示該方法覆蓋父類中的方法。

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}複製程式碼

3. @SuppressWarnings
所標註內容產生的警告,編譯器會對這些警告保持靜默。

@Target({ElementType.TYPE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.CONSTRUCTOR, ElementType.LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}
/*
value可取的值:
deprecation  -- 使用了不贊成使用的類或方法時的警告
unchecked    -- 執行了未檢查的轉換時的警告,例如當使用集合時沒有用泛型 (Generics) 來指定集合儲存的型別。
fallthrough  -- 當 Switch 程式塊直接通往下一種情況而沒有 Break 時的警告。
path         -- 在類路徑、原始檔路徑等中有不存在的路徑時的警告。
serial       -- 當在可序列化的類上缺少 serialVersionUID 定義時的警告。
finally      -- 任何 finally 子句不能正常完成時的警告。
all          -- 關於以上所有情況的警告。
*/複製程式碼

5. 處理註解

Java處理註解有兩種方式:

  1. 使用apt來在編譯時期生成相應的程式碼,通過註解處理器(AnnotationProcessor)來處理

  2. 在執行時通過反射獲取註解資訊來處理

這塊之後專門來學習,這篇文章不贅述了。

6. 註解的作用

  1. 生成文件。這是最常見的,也是java 最早提供的註解。常用的有@see @param @return 等

  2. 程式碼分析,跟蹤程式碼依賴性。如JUnit框架的註解使用。

  3. 在編譯時進行格式檢查。如@override 放在方法前,如果你這個方法並不是覆蓋了超類方法,則編譯時就能檢查出。

結語

本篇文章介紹註解的基本概念和作用,對註解的基本有個清晰的瞭解,之後再單獨寫對註解的處理,ButterKnife是個很好的學習例子。



參考:
Java Annotation認知(包括框架圖、詳細介紹、示例說明)
Java註解全面解析
Java深度歷險(六)——Java註解

相關文章