1. 程式人生 > >Android 開發中需要知道的註解

Android 開發中需要知道的註解

CSDN圖示

一、什麼是註解(Annotation)?

 
簡單的說就是元資料(Metadata),即一種描述資料的資料。所以說註解就是原始碼的元資料。更具體的就是一種應用於類、方法、引數、變數、構造器及包宣告中的特殊修飾符。它是一種由JSR-175標準選擇用來描述元資料的一種工具。JDK5中引入了Metadata很容易的就能夠呼叫註解。

二、為什麼引入註解?

在Annotation出現前,XML被廣泛的應用於描述元資料。在開發過程中一些應用開發人員和架構師發現XML的維護越來越糟糕。他們希望使用一些和程式碼緊耦合的東西,而不是像XML那樣和程式碼是鬆耦合的(在某些情況下甚至是完全分離的)程式碼描述,於是就出現了註解。目前,許多框架將XML和Annotation兩種方式結合使用,平衡兩者之間的利弊。

三、註解的語法與定義形式

  • 以@interface關鍵字定義
  • 註解包含成員,成員以無引數的方法的形式被宣告。其方法名和返回值定義了該成員的名字和型別。
  • 成員賦值是通過@Annotation(name=value)的形式。
  • 註解需要標明註解的生命週期,註解的修飾目標等資訊,這些資訊是通過元註解實現。

Java提供了四種元註解,專門負責新註解的建立工作,即註解其他註解。

  • @Target
    定義了Annotation所修飾的物件範圍,Annotation可被用於 packages、types(類、介面、列舉、Annotation型別)、型別成員(方法、構造方法、成員變數、列舉值)、方法引數和本地變數(如迴圈變數、catch引數)。在Annotation型別的宣告中使用了target可更加明晰其修飾的目標。取值(): 

    • ElementType.CONSTRUCTOR:用於描述構造器
    • ElementType.FIELD:用於描述域
    • ElementType.LOCAL_VARIABLE:用於描述區域性變數
    • ElementType.METHOD:用於描述方法
    • ElementType.PACKAGE:用於描述包
    • ElementType.PARAMETER:用於描述引數
    • ElementType.TYPE:用於描述類、介面(包括註解型別) 或enum宣告
    • ElementType. ANNOTATION_TYPE:註解上使用的元註解
  • @Retention
    定義了該Annotation被保留的時間長短:某些Annotation僅出現在原始碼中,而被編譯器丟棄;而另一些卻被編譯在class檔案中;編譯在class檔案中的Annotation可能會被虛擬機器忽略,而另一些在class被裝載時將被讀取(請注意並不影響class的執行,因為Annotation與class在使用上是被分離的)。取值:

    • RetentionPoicy.SOURCE:註解只保留在原始檔,當Java檔案編譯成class檔案的時候,註解被遺棄;用於做一些檢查性的操作,比如 @Override 和 @SuppressWarnings

    • RetentionPoicy.CLASS:註解被保留到class檔案,但jvm載入class檔案時候被遺棄,這是預設的生命週期;用於在編譯時進行一些預處理操作,比如生成一些輔助程式碼(如 ButterKnife)

    • RetentionPoicy.RUNTIME:註解不僅被儲存到class檔案中,jvm載入class檔案之後,仍然存在;用於在執行時去動態獲取註解資訊。

  • @Documented
    標記註解,用於描述其它型別的註解應該被作為被標註的程式成員的公共API,因此可以被例如javadoc此類的工具文件化,不用賦值。

  • @Inherited
    標記註解,允許子類繼承父類的註解。

上面的理論可能不太直觀,下面以與註解Target舉例說明一下:

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

1:元註解@Retention,成員value的值為RetentionPolicy.RUNTIME
2:元註解@Target,成員value是個陣列,用{}形式賦值,值為ElementType.ANNOTATION_TYPE
3:成員名稱為value,型別為ElementType[]

!注意:如果成員名稱是value,在賦值過程中可以簡寫。如果成員型別為陣列,但是隻賦值一個元素,則也可以簡寫。如上面的簡寫形式為:

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

框架中常見註解

  • JDK內建的其他註解
    @Override、@Deprecated、@SuppressWarnings、@SafeVarargs、@FunctionalInterface、@Resources等。
  • Android SDK內建的註解
    • 資源引用限制類:用於限制引數必須為對應的資源型別
      @AnimRes @AnyRes @ArrayRes @AttrRes @BoolRes @ColorRes
    • 執行緒執行限制類:用於限制方法或者類必須在指定的執行緒執行
      @AnyThread @BinderThread @MainThread @UiThread @WorkerThread
    • 引數為空性限制類:用於限制引數是否可以為空
      @NonNull @Nullable
    • 類型範圍限制類:用於限制標註值的值範圍
      @FloatRang @IntRange
    • 型別定義類:用於限制定義的註解的取值集合
      @IntDef @StringDef

Android SDK 內建的註解都在包com.android.support:support-annotations裡,具體的使用介紹見官方文件:傳送門

Java註解的思維導圖

最後引用網上大神的一張思維導圖如下:

CSDN圖示