☕ Java註解-筆記
什麼是註解
註解(Annotation)是放在Java原始碼的類、方法、欄位、引數前的一種特殊”註釋“。
註釋會被編譯器直接忽略,註解則可以被編譯器打包進入class檔案,因此,註解是一種用作標註的“元資料”,一種介面型別。
註解的作用
註解並不能改變程式的執行結果,也不會影響程式執行的效能。有些註解可以在編譯時給使用者提示或警告,有的註解可以在執行時讀寫位元組碼檔案資訊。
- 生成幫助文件。常用有
@see、@param、 @return
- 跟蹤程式碼依賴性,實現替代配置檔案功能。(常見的是 Spring 2.5 開始的基於註解配置,作用就是減少配置。)
- 在編譯時進行格式檢查。
常用註解
-
@Override
:用來指定方法重寫的,只能修飾方法並且只能用於方法重寫,不能修飾其它的元素。 -
@Deprecated
:用來註解類、介面、成員方法和成員變數等,用於表示某個元素(類、方法等)已過時。當其他程式使用已過時的元素時,編譯器將會給出警告。Java 9 為 @Deprecated 註解增加了以下兩個屬性:
-
forRemoval
:該 boolean 型別的屬性指定該 API 在將來是否會被刪除。 -
since
:該 String 型別的屬性指定該 API 從哪個版本被標記為過時。public class DeprecatedTest { public static void main(String[] args) { new Test().print(); } } class Test { @Deprecated(since="6", forRemoval=true) public void print() { System.out.println("啊對對對"); } }
-
-
@SuppressWarnings
:被該註解修飾的程式元素(及其所有子元素)取消顯示指定的編譯器警告,且會一直作用於該程式元素的所有子元素。註解的使用有以下三種:抑制警告關鍵字
- 抑制單型別的警告:
@SuppressWarnings("unchecked")
- 抑制多型別的警告:
@SuppressWarnings("unchecked","rawtypes")
- 抑制所有型別的警告:
@SuppressWarnings("unchecked")
使用
@SuppressWarnings({ "deprecation" })
註解了HelloWorld.java 的 main 方法:程式程式碼的警告沒有了
- 抑制單型別的警告:
-
@SafeVarargs
:用來抑制呼叫可變引數方法時,提供的引數型別不一致的警告。不適用於非 static 或非 final 宣告的方法。
定義註解
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
// 註解的引數類似無引數方法
元註解
元註解(meta annotation),負責對其它註解進行說明的註解,自定義註解時可以使用元註解。
-
@Target
:最常用的元註解使用
@Target
可以定義Annotation
能夠被應用於原始碼的哪些位置:- 類或介面:
ElementType.TYPE
; - 欄位:
ElementType.FIELD
; - 方法:
ElementType.METHOD
; - 構造方法:
ElementType.CONSTRUCTOR
; - 方法引數:
ElementType.PARAMETER
。
// 定義註解@Report用在方法上 @Target(ElementType.METHOD) public @interface Report { int type() default 0; ... } // 定義註解@Report可用在方法或欄位上 @Target({ ElementType.METHOD, ElementType.FIELD }) public @interface Report { ... }
- 類或介面:
-
@Retention
用於描述註解的生命週期,也就是該註解被保留的時間長短:
@Retention
註解中的成員變數(value)用來設定保留策略,value 是java.lang.annotation.RetentionPolicy
列舉型別,RetentionPolicy
有 3 個列舉常量- 僅編譯期:
RetentionPolicy.SOURCE
;
- 僅編譯期:
-
僅class檔案:
RetentionPolicy.CLASS
;- 執行期:
RetentionPolicy.RUNTIME
。
如果
@Retention
不存在,則該Annotation
預設為CLASS
。通常自定義的Annotation
都是RUNTIME
,所以必須加上@Retention(RetentionPolicy.RUNTIME)
這個元註解 - 執行期:
-
@Inherited
- 使用
@Inherited
定義子類是否可繼承父類定義的註解 - 僅針對
@Target(ElementType.TYPE)
型別的註解有效 - 且僅針對類的繼承,對介面繼承無效
- 子類預設也定義父類的註解
- 使用
定義註解完整步驟
- 用@interface定義註解
- 新增引數、預設值
- 用元註解配置註解
// 3. 用元註解配置註解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Report { // 1. 用@interface定義註解
// 2. 新增引數、預設值
int type() default 0;
String level() default "info";
String value() default "";
}
註解分類
根據註解是否包含成員變數,可以分為如下兩類。
- 標記註解:沒有定義成員變數的註解型別被稱為標記註解。這種註解僅利用自身的存在與否來提供資訊,如前面介紹的 @Override、@Test 等都是標記註解。
- 元資料註解:包含成員變數的註解,因為它們可以接受更多的元資料,所以也被稱為元資料註解。
抑制警告關鍵字
關鍵字 | 用途 |
---|---|
all | 抑制所有警告 |
boxing | 抑制裝箱、拆箱操作時候的警告 |
cast | 抑制對映相關的警告 |
dep-ann | 抑制啟用註釋的警告 |
deprecation | 抑制過期方法警告 |
fallthrough | 抑制在 switch 中缺失 breaks 的警告 |
finally | 抑制 finally 模組沒有返回的警告 |
hiding | 抑制相對於隱藏變數的區域性變數的警告 |
incomplete-switch | 忽略不完整的 switch 語句 |
nls | 忽略非 nls 格式的字元 |
null | 忽略對 null 的操作 |
rawtypes | 使用 generics 時忽略沒有指定相應的型別 |
restriction | 抑制禁止使用勸阻或禁止引用的警告 |
serial | 忽略在 serializable 類中沒有宣告 serialVersionUID 變數 |
static-access | 抑制不正確的靜態訪問方式警告 |
synthetic-access | 抑制子類沒有按最優方法訪問內部類的警告 |
unchecked | 抑制沒有進行型別檢查操作的警告 |
unqualified-field-access | 抑制沒有許可權訪問的域的警告 |
unused | 抑制沒被使用過的程式碼的警告 |