理解 Java 註解 – Java @annotations 教程
已發表: 2019-10-22
Java 中如何以及在何處使用註解?
在 Java 計算機編程語言中,註解是一種特殊形式的句法元數據,可以添加到 Java 源代碼中。
類、方法、變量、參數和包可以被註釋。 與 Javadoc 標記不同,Java 註釋可以是反射性的,因為它們可以嵌入到編譯器生成的類文件中,並且可以由 Java VM 保留以在運行時進行檢索。
可以從 Java 中現有的元註釋中創建元註釋,這使得這個概念更加複雜。
Java 定義了一組內置於語言中的註釋。

應用於java代碼的註釋:
- @Override – 檢查函數是否為覆蓋。 如果在其中一個父類中找不到該函數,則會導致編譯警告。
- @Deprecated – 將函數標記為已過時。 如果使用該函數,則會導致編譯警告。
- @SuppressWarnings – 指示編譯器抑制註釋參數中指定的編譯時警告。
應用於其他註釋的註釋:
- @Retention – 指定標記註解的存儲方式——無論是僅在代碼中、編譯到類中還是在運行時通過反射可用。
- @Documented – 標記另一個註釋以包含在文檔中。
- @Target – 標記另一個註解以限制該註解可以應用到的 Java 元素類型。
- @Inherited - 將另一個註解標記為繼承到被註解的類的子類(默認情況下註解不會被繼承到子類)。
讓我們通過示例來看看這些:
1)@Override註解:
它的存在向編譯器表明帶註釋的方法必須覆蓋現有的超類方法。
@Override最常見的用例是使用Object方法:
1 2 3 4 |
@ Override public int hashValue ( ) { System . out . Println ( "This method is using @Override Annotation" ) ; } |
創建@Override的主要原因是為了處理簡單的印刷錯誤。
例如,一個方法被錯誤地聲明為
1 |
public int hashvalue ( ) { . . . } |
實際上不是覆蓋 - 方法名稱全是小寫字母,因此它與hashValue()方法的名稱不完全匹配。 然而,它會編譯得很好。 這樣的錯誤很容易犯,也很難捕捉,這是一個危險的組合。 使用@Override註釋可防止您犯此類錯誤。
每當您覆蓋超類方法時,您應該養成使用@Override的習慣。

2)@Deprecated註解:
此註釋表明標記的元素已被棄用,不應再使用。 每當程序使用帶有@Deprecated
註釋的方法、類或字段時,編譯器都會生成警告。
當一個元素被棄用時,還應該使用 Javadoc @deprecated
標記對其進行記錄,如以下示例所示。
1 2 3 4 |
< strong > @ Deprecated < / strong > static void deprecatedMethod ( ) { System . out . Println ( "This method is Deprecated.." ) ; } |
3)@SuppressWarnings 註釋:
只是告訴編譯器,請不要大喊大叫。 我知道我在做什麼。
1 2 3 4 |
@ SuppressWarnings ( "serial" ) public class OldCode implements Serializable { System . out . Println ( "This is Old Code.." ) ; } |
4)@Retention註解:
保留註釋指示將在何處保留此類型的註釋以及保留多長時間。
有三個值:
- RetentionPolicy.SOURCE — 這種類型的註解將只保留在源代碼級別,編譯器會忽略它。
- RetentionPolicy.CLASS — 編譯器會在編譯時保留此類型的註解,但會被 VM 忽略。
- RetentionPolicy.RUNTIME — VM 將保留此類型的註釋,因此它們只能在運行時讀取。
1 2 3 4 |
@ Retention ( RetentionPolicy . RUNTIME ) public @ interface Crunchify_Retention { String returnSomething ( ) ; } |
5)@記錄註釋:
1 2 3 4 |
@ Documented public @ interface Crunchify_Documented { String writeDocument ( ) ; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class DocumentedAnnotations { public static void main ( String arg [ ] ) { new DocumentedAnnotations ( ) . performRetention ( ) ; new DocumentedAnnotations ( ) . performDocumented ( ) ; } @ Crunchify_Retention ( returnSomething = "Hello retention test" ) public void performRetention ( ) { System . out . printf ( "Testing annotation 'Crunchify_Retention'" ) ; } @ Crunchify_Documented ( writeDocument = "Hello document" ) public void performDocumented ( ) { System . out . printf ( "Testing annotation 'Crunchify_Documented'" ) ; } } |
現在嘗試運行 Java Doc 命令並查看輸出。

6)@Target註解:
目標指示可以使用帶註釋的註釋類型的實例來註釋哪些程序元素。 Target 的值是java.lang.annotation.ElementType
枚舉的成員之一:
- ANNOTATION_TYPE。 帶註釋的註釋類型可用於註釋註釋類型聲明。
- 構造函數。 帶註釋的註釋類型可用於註釋構造函數聲明。
- 場地。 帶註釋的註釋類型可用於註釋字段聲明。
- 本地變量。 帶註釋的註釋類型可用於註釋局部變量聲明。
- 方法。 帶註釋的註釋類型可用於註釋方法聲明。
- 包裹。 帶註釋的註釋類型可用於註釋包聲明。
- 範圍。 帶註釋的註釋類型可用於註釋參數聲明。
- 類型。 帶註釋的註釋類型可用於註釋類型聲明。
1 2 3 4 |
@ Target ( value = METHOD ) You can have multiple values in the Target annotation . @ Target ( value = { TYPE , FIELD , METHOD , PARAMETER , CONSTRUCTOR , LOCAL_VARIABLE } ) |
7)@Inherited註解:
顧名思義, @Inherited
註解類型由註解類型的子類繼承。
1 2 3 4 5 6 7 8 9 10 |
@ Inherited @ interface ForEveryone { } @ interface JustForMe { } @ ForEveryone @ JustForMe class Superclass { } class Subclass extends Superclass { } |
在這個例子中, Superclass
已經被明確地註釋了@ForEveryone
和@JustForMe
。 Subclass
沒有被明確標記為任何一個; 但是,它繼承@ForEveryone
,因為後者帶有@Inherited
註釋。
@JustForMe
沒有註釋,所以它沒有被Subclass
繼承。
這是一個類級別的註釋
