再論Java註解

一、什麼是註解?

註解其實就是代碼中的特殊標記,這些標記可以在編譯、類加載、運行時被讀取,並執行相對應的處理

二、爲什麼要用註解開發?

傳統的方式是,通過配置文件(xml文件 )來告訴類是如何運行的,使用註解開發後,通過註解告訴類是如何運行

三、元註解(註解的註解)

  • @Target:註解作用目標(即:被描述的註解可以用在什麼地方)

    • @Target(ElementType.TYPE)——接口、類、枚舉、註解
    • @Target(ElementType.FIELD)——字段、枚舉的常量
    • @Target(ElementType.METHOD)——方法
    • @Target(ElementType.PARAMETER)——方法參數
    • @Target(ElementType.CONSTRUCTOR) ——構造函數
    • @Target(ElementType.LOCAL_VARIABLE)——局部變量
    • @Target(ElementType.ANNOTATION_TYPE)——註解
    • @Target(ElementType.PACKAGE)——包
  • @Retention:註解的保留位置,用於描述註解的生命週期(SOURCE->CLASS -> RUNTIME

    • RetentionPolicy.SOURCE:這種類型的Annotations只在源代碼級別保留,編譯時就會被忽略,在class字節碼文件中不包含
    • RetentionPolicy.CLASS:這種類型的Annotations編譯時被保留,默認的保留策略,在class文件中存在,但JVM將會忽略,運行時無法獲得
    • RetentionPolicy.RUNTIME:這種類型的Annotations將被JVM保留,所以他們能在運行時被JVM或其他使用反射機制的代碼所讀取和使用。
  • @Document:說明該註解將被包含在javadoc

  • @Inherited:是一個標識,用來修飾註解

    • 作用:如果一個類用上了@Inherited修飾的註解,那麼其子類也會繼承這個註解

      注意:

      • 接口用上個@Inherited修飾的註解,其實現類不會繼承這個註解
      • 父類的方法用了@Inherited修飾的註解,子類也不會繼承這個註解

四、JDK基本註解

4.1 @Override

重寫註解

@Overried是告訴編譯器要檢查該方法是實現父類的…可以幫我們避免一些低級的錯誤…

比如,我們在實現equals()方法的時候,把euqals()打錯了,那麼編譯器就會發現該方法並不是實現父類的,與註解@Override衝突,於是就會給予錯誤

4.2 @Deprecated

過時註解

在Java迭代中,覺得某些方法設計不好,而爲了兼容老版本,不能直接拋棄掉,於是加上註解表明過時的,不建議再用

Date對象中的toLocalString()就被設計爲過時的

@Deprecated
public String toLocaleString() {
    DateFormat formatter = DateFormat.getDateTimeInstance();
    return formatter.format(this);
}

4.3 SuppressWarnings

鎮壓警告註解

該註解可以抑制編譯器給我們提示的安全警告

4.4 @SafeVarargs

Java7 “堆污染”警告註解

在聲明具有模糊類型(比如:泛型)的可變參數的構造函數或方法時,Java編譯器會報unchecked警告。鑑於這些情況,如果程序員斷定聲明的構造函數和方法的主體不會對其varargs參數執行潛在的不安全的操作,可使用@SafeVarargs進行標記,這樣的話,Java編譯器就不會報unchecked警告

4.5 @FunctionalInterface

@FunctionalInterface函數式接口註解

該註解指定該接口是函數式接口

五、自定義註解

需求:給方法或類注入信息

5.1 標記Annotation

沒有任何成員變量的註解稱作爲標記註解,@Overried就是一個標記註解

public @interface MyAnnotation {
}

5.2 元數據Annotation

註解是可以帶成員變量的,定義帶成員變量的註解叫做元數據Annotation

在註解中定義成員變量,語法類似於聲明方法一樣….

public @interface MyAnnotation {
    String username();
    int age();
}

5.3 使用自定義註解

5.3.1 基本使用

給add方法注入username和age這 兩個參數

//註解擁有什麼屬性,在修飾的時候就要給出相對應的值
@MyAnnotation(username = "xiaoming", age = 20)
public void add(String username, int age) {
}

5.3.2 默認值

註解聲明屬性的時候給出默認值,這樣我們就可以在使用註解的時候省略掉屬性賦值

public @interface MyAnnotation {
    String username() default "xiaoming";
    int age() default 20;
}

使用註解

@MyAnnotation()
public void add(String username, int age) {
}

5.3.3 註解屬性爲value

有一種特殊的情況,如果註解上只有一個屬性,並且屬性的名稱爲value,那麼在使用的時候,我們可以不寫value,直接賦值給它就行

public @interface MyAnnotation2 {
   String value();
}

使用註解

@MyAnnotation2("zhongfucheng")
public void find(String id) {
}

六、總結

  1. 注入對象的步驟:得到想要注入的對象屬性,通過屬性得到註解的信息,通過屬性的寫方法將註解的信息注入到對象上,最後將對象賦給類

  2. 註解其實就是兩個作用:

    1. 讓編譯器檢查代碼
    2. 將數據注入到方法、成員變量、類上
  3. 在JDK中註解分爲

    1. 元Annotaion:在annotaion包下,常用於修飾其他的Annotation定義
    2. 基本Annotation:在lang包下,用於常用於標記該方法,抑制編譯器警告等
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章