天天看點

Java 中的注解有哪些?如何自定義注解?(進階崗位必背)Java 中的注解有哪些?如何自定義注解?(進階崗位必背)

Java 中的注解有哪些?如何自定義注解?(進階崗位必背)

熟悉 C#的人應該知道,C#中的 Attribute 類,實作對中繼資料(資料的資料)的程式設計支援。

Java 也是個要面子的語言,迫不得已之下,也在 java1.5 的時候,搞了一個注解(Annotation)出來。有圖為證。

Java 中的注解有哪些?如何自定義注解?(進階崗位必背)Java 中的注解有哪些?如何自定義注解?(進階崗位必背)
注解的概念

白話的說,注解就是修飾類,方法,屬性,參數等元素的一個标注,它本身不包含任何邏輯,隻是标注了這些資訊,标注給誰看呢?有些标注是給編譯器看,提醒編譯器編譯時要差別對待一下。有些标注給 JVM 看,JVM 在運作的時候要注意這個标注是不是有新的行為要觸發。

Java 自帶的标注

jdk1.8,自帶了 5 種标注。

  • @SuppressWarnings —— 這個标記是給編譯器看的,編譯的時候就不會再出現警告資訊。
  • @Override —— 強制一個子類必須覆寫父類的方法
  • @Deprecated —— 标記某個元素已經過時,這個是給編譯器看的,編譯的時候就會給出警告。
  • @SafeVarargs —— Java 會對堆污染的方法編譯警告,這個标注是壓制這個警告。
  • @FunctionInterface —— Java8 新增的,用于标注某個接口必須是函數式接口。可參考 《java-8-中的拉姆達表達式是什麼?》

這 5 種标注的更詳細資訊,可以自行檢視其 API。

注解的注解——元注解

搞笑的是,我們在定義注解的時候,還需要用到别的注解。這種注解就叫元注解。

自帶的元注解有 5 種:

  • @Retention
  • @Target
  • @Document
  • @Inherited
  • @Repeatable

@Retention 修飾這個注解可以在何時被看到,有 3 種政策,

  • RetentionPolicy.CLASS 這是預設政策。這種政策下,注解在與.class 檔案中,運作時 JVM 無法看到它。
  • RetentionPolicy.SOURCE  這種政策中,不存在.class 檔案,更不能運作時可見,隻能在源碼中看到。
  • RetentionPolicy.RUNTIME 這種政策下可以在運作時通路到。通常情況下,我們都會結合反射來做一些事情。

@Target 可以選擇的參數值有如下這些:

  • ElementType.ANNOTATION_TYPE(注:修飾注解)
  • ElementType.CONSTRUCTOR
  • ElementType.FIELD
  • ElementType.LOCAL_VARIABLE
  • ElementType.METHOD
  • ElementType.PACKAGE
  • ElementType.PARAMETER
  • ElementType.TYPE(注:任何類型,即上面的的類型都可以修飾)

@Document 标注過的注解 A,在使用了注解 A 後,javadoc 工具在生成文檔的時候,會把注解 A 的資訊放在文檔中。

@Inherited 标注過的注解 A,父類中使用 A 注解後,子類也會自動的繼承了 A 注解。

java.lang.annotation.Inherited
@Inherited
public @interface MyAnnotation {
}
 
@MyAnnotation
public class MySuperClass { ... }
 
public class MySubClass extends MySuperClass { ... }           

複制

上述代碼,子類通過繼承也有了 MyAnnotation 注解。

@Repeatable 是 Java8 中新增的注解,使得代碼可讀性更好點,看一個例子了解它的用途。

沒有用@Repeatable 的時候

public @interface Authority {
     String role();
}
 
public @interface Authorities {
    Authority[] value();
}
 
public class RepeatAnnotationUseOldVersion {
    
    @Authorities({@Authority(role="Admin"),@Authority(role="Manager")})
    public void doSomeThing(){
    }
}           

複制

使用@Repeatable 的時候

@Repeatable(Authorities.class)
public @interface Authority {
     String role();
}
 
public @interface Authorities {
    Authority[] value();
}
 
public class RepeatAnnotationUseNewVersion {
    @Authority(role="Admin")
    @Authority(role="Manager")
    public void doSomeThing(){ }
}           

複制

那麼如何自定義一個注解,參考 java 中如何自定義注解?/ ‎