【java】細說 JAVA中 標註 註解(annotation)

Java註解是附加在代碼中的一些元信息,用於一些工具在編譯、運行時進行解析和使用,起到說明、配置的功能。
註解不會也不能影響代碼的實際邏輯,僅僅起到輔助性的做用java

下面咱們來詳細說說這個註解,究竟是怎麼一回事,一步一步看下去,總會後收穫。編程

註解起源:Annotation(註解)是JDK5.0及之後版本引入的。在java.lang.annotation包中。工具

註解做用:它能夠用於建立文檔,跟蹤代碼中的依賴性,甚至執行基本編譯時檢查。spa

註解格式:註解是以‘@註解名’在代碼中存在的code

註解分類:標記註解、單值註解、完整註解三類對象

另外:它都不會直接影響到程序的語義,只是做爲註解(標識)存在,咱們能夠經過反射機制編程實現對這些元數據的訪問。blog

元註解說,我先來上陣-----繼承

------------------------------main-----------------------------------接口

1、元註解:

元註解功能:就是對其餘註解進行註解。生命週期

咱們它的功能劃分爲三類:

  編寫文檔:經過代碼裏標識的元數據生成文檔;

  代碼分析:經過代碼裏標識的元數據對代碼進行分析;

  編譯檢查:經過代碼裏標識的元數據讓編譯器能實現基本的編譯檢查。

元註解包括:@Retention @Target @Document @Inherited四種。


@Target 註解:

---------------------------------------------------

@Target解釋:

  @Target說明了Annotation所修飾的對象範圍:

    Annotation可被用於 packages、types(類、接口、枚舉、Annotation類型)、類型成員(方法、構造方法、成員變量、枚舉值)、方法參數和本地變量(如循 環變量、catch參數)。

    在Annotation類型的聲明中使用了target可更加明晰其修飾的目標。

@Target做用:用於描述註解的使用範圍(即:被描述的註解能夠用在什麼地方)

@Target 的java源碼:

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

 

  備註:先解釋一下 interface 表示接口,而@interface表示annotation

——————————————————————————

ElementType取值:

    經過源碼能夠看到,ElementType ,它的取值有:

    1.CONSTRUCTOR:用於描述構造器
    2.FIELD:用於描述域
    3.LOCAL_VARIABLE:用於描述局部變量
    4.METHOD:用於描述方法
    5.PACKAGE:用於描述包
    6.PARAMETER:用於描述參數
    7.TYPE:用於描述類、接口(包括註解類型) 或enum聲明

------------------------------------------------

實例: (咱們自定義了兩個自定義註解,按照上面咱們給出的取值含義,@table將會用於類、接口或enum聲明)

@Target(ElementType.TYPE)
public @interface Table {
    /**
     * 數據表名稱註解,默認值爲類名稱
     * @return
     */
    public String tableName() default "className";
}

@Target(ElementType.FIELD)
public @interface NoDBColumn {

}

 那麼到這裏,咱們的@Target 元註解解釋完畢,有不明白地方, @企鵝:2783309477

 


 @Retention註解:

 

@Retention 精簡解釋:

  就是對自定義註解的生命週期的管理

@Retention 詳細解釋:

  @Retention定義了該Annotation被保留的時間長短:某些Annotation僅出如今源代碼中,而 被編譯器丟棄;而另外一些卻被編譯在class文件中;編譯在class文件中的Annotation可能會被虛擬機忽略,而另外一些在class被裝載時將 被讀取(請注意並不影響class的執行,由於Annotation與class在使用上是被分離的)。使用這個meta-Annotation能夠對 Annotation的「生命週期」限制

 ——————————————————————————————

@Retention: 定義註解的保留策略

  @Retention(RetentionPolicy.SOURCE)    //註解僅存在於源碼中,在class字節碼文件中不包含
  @Retention(RetentionPolicy.CLASS)      // 默認的保留策略,註解會在class字節碼文件中存在,但運行時沒法得到
  @Retention(RetentionPolicy.RUNTIME)   // 註解會在class字節碼文件中存在,在運行時能夠經過反射獲取到

 ——————————————————————————————

@Retention java源碼:

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

 

  經過源代碼能夠看到RetentionPolicy可取值。那麼接下來

———————————————————————————————

@Retention  取值:

  RetentionPolicy可取值:

    1.SOURCE:在源文件中有效(即源文件保留)
    2.CLASS:在class文件中有效(即class保留)
    3.RUNTIME:在運行時有效(即運行時保留)

@Retention 實例:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Column {
    public String name() default "fieldName";
    public String setFuncName() default "setField";
    public String getFuncName() default "getField"; 
    public boolean defaultDBValue() default false;
}

 

備註:也一樣,能夠看出來,Column將會有在運行時有效範圍。

  通常格式:

  @Retention(RetentionPolicy.SOURCE)   //註解僅存在於源碼中,在class字節碼文件中不包含

  @Retention(RetentionPolicy.CLASS)     // 默認的保留策略,註解會在class字節碼文件中存在,但運行時沒法得到,

  @Retention(RetentionPolicy.RUNTIME)   // 註解會在class字節碼文件中存在,在運行時能夠經過反射獲取到

  OK,這個就解釋到這裏,有不明白 @小企鵝:2783309477(如是),接下來


 @Documented 元註解:

  @Documented用於描述其它類型的annotation應該被做爲被標註的程序成員的公共API,

  所以能夠被例如javadoc此類的工具文檔化。

  Documented是一個標記註解,沒有成員。

@Document java源碼:

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

 

@Document 實例:

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Column {
    public String name() default "fieldName";
    public String setFuncName() default "setField";
    public String getFuncName() default "getField"; 
    public boolean defaultDBValue() default false;
}

 

 


  @Inherited 元註解:
  
@Inherited 解釋:
  是一個標記註解,@Inherited闡述了某個被標註的類型是被繼承的。
  也就是說,若是被它修飾的annotation類型用在一個類上面,這個annotation 將被用在子類中。
   注意:
     一、@Inherited annotation類型是被標註過的class的子類所繼承。
      類並不從它所實現的接口繼承annotation,方法並不從它所重載的方法繼承annotation。
    二、當@Inherited annotation類型標註的annotation的Retention是RetentionPolicy.RUNTIME,
      則反射API加強了這種繼 承性。若是咱們使用java.lang.reflect去查詢一個@Inherited annotation
      類型的annotation時,反射代碼檢查將展開工做:檢查class和其父類,直到發現指定的annotation類型
      被發現, 或者到達類繼承結構的頂層。

 
 未完待續(自定義註解/默認註解/...)
相關文章
相關標籤/搜索