1. 程式人生 > >Java 註解(原理及其使用)

Java 註解(原理及其使用)

def ava IT 使用範圍 自動化測試 決定 加載 del 特定

  一、註解(annotation)介紹

  Java在JDK5中引入源代碼的註解機制。

  1、什麽是註解?

  註解為代碼添加了元數據,元數據是關於數據的組織、數據域及其關系的說明信息。

  更通俗的說,註解為程序元素添加了更加直觀的說明,這些說明信息與程序的業務邏輯無關,並且是供特定的工具或框架使用的。

  註解可以被編譯器嵌入在class文件中,從而使得JVM在運行時能夠檢索到,因此註解可以被反射;

  註解可以不直接影響代碼的執行,也可以通過它改變代碼的執行流程。

  

  2、註解的目標

  註解是一種接口,通過反射機制相關的API能訪問註解信息。程序框架或工具中的類根據這些信息來決定如何使用程序元素或改變框架自身的行為。但是註解不會影響程序代碼實的實際執行。

  註解的目的在於對編譯器或依托框架(Spring)說明程序的某些信息,每一個註解對應於一個實際的註解類型。

  3、Java中註解的作用

  • 編寫文檔
  • 編譯檢查
  • 項目構建說明
  • 運行時指令
  • 跟蹤代碼依賴性

  4、註解的使用

  @註解名稱(配置參數)

  當註解有多個參數時,必須聲明參數名稱;而且註解的配置參數的值必須是編譯時的常量。

  註解可以被看成一個XML元素,該元素可以有不同的預定義的屬性,而屬性的值是可以在聲明該元素的時候自行指定的。在代碼中使用註解,就相當於把一部分元素據從XML文件移到了代碼之中,在一個地方管理和維護,有利於保持代碼和元數據的一致性。

  

  5、創建自定義註解

  步驟:

  (1)通過@interface 聲明註解名稱,然後在{ }中聲明註解的成員屬性(即參數)。

  (2)使用內置的元註解標註功能並對註解的使用範圍進行限制。

  ps:自定義註解時會自動繼承java.lang.annotation.Annotation

/*Version註解*/
public @interface Version{
    double number();      //註解成員類型為double,名為number。
}

/*Author註解*/
public @interface Author{
     String name() default "unknown";     //
註解成員類型為String,名為name。 }

  值得強調的是,null不能作為默認值!

  註解的使用:

@Author(name="Johny")
@Version(number=1.0)
publice class MyConfig{
         ...
}

  二、元註解(Meta-Annotation)

  元註解專門用來約束其它註解,有四個:

  • @Target
  • @Retention
  • @Documented
  • @Inherited

  1、@Retention

  功能:定義註解被保留的持續時間,即註解的生命周期。

  配置參數:RetentionPolicy

public enum RetentionPolicy{
   SOURCE,
   CLASS,
   RUNTIME,    
}

  某些註解僅出現在源代碼中,會被編譯器丟棄;還有一些會被編譯在class文件中,雖然他們會被類加載器讀取,但是有可能會被JVM忽略。

  (編譯器默認把註解信息保留在.class文件中,為編譯器或工具程序運行時提供信息)

  如果程序員打算設計代碼分析工具,就必須讓JVM讀出註解信息,以便在分析程序時使用。這時就要設置元註解@Retention的RetentionPolicy為RUNTIME,然後搭配 反射機制,通過Class類的getAnnotation()方法獲得指定註解,這樣就可以在運行時提取出註解的信息。

  2、@Target

  功能:說明註解所修飾的對象的範圍

  配置參數: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 }

/*註解Version只能用於修飾構造方法和方法*/
@Target({ElementType.CONSTRUCTOR,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Version{
    double number();
} 

  3、@Documented

  功能:將註解的信息加入到幫助文件中,因為默認不會添加註解信息。

  配置參數:沒有。

  使用@Documented修飾註解類型時必須同時使用@Retention,配置參數RetentionPolicy為RUNTIME。

  4、@Inherited

  功能:控制註解是否會影響子類,即讓註解類型被繼承後任然保留在子類中。

  5、運行時讀取註解

  註解的解析完全依賴於反射機制。程序通過反射獲取某個類的Class對象後,就可以調用該對象的多個方法來取得該類的註解信息。

  java.lang.reflect包所提供的反射API擴充了讀取運行時註解信息的能力,它新增了AnnotatedElement接口,該接口代表程序中可以接受註解的程序元素。

  三、註解與反射的應用

  1、過濾方法

  註解可以修飾方法,以便指定該方法的性質或類型,從而使得方法的調用者根據該註解來過濾能夠調用的方法。在這類應用中,註解起到標記作用,指示方法是否符合條件。

  2、自動化測試框架

  測試是程序設計不可缺少的環節,是提高代碼健壯性的必要手段。

  但代碼測試由於要覆蓋不同的代碼執行邏輯和路徑,往往極為復雜,因此自動化測試框架能有效提高代碼測試的效率,起到事倍功半的效果。

  以下實例演示了如何通過註解來實現一個簡單的測試框架,從而自動化地實現單元測試。這一做法在單元測試框架JUnit中大量應用。

  四、單一抽象方法註解

  單一抽象方法(Single Abstract Method,SAM)註解@FunctionalInterface的作用是限制接口有且僅有一個未實現的方法,當然可以有多個已經實現的default方法,顯然,它是為Lambda表達式服務的。

Java 註解(原理及其使用)