2005 年,隨著 Java 5 的到來,我們開始了解稱為註解的新實體。

註釋是一種特殊形式的語法元數據,可以在代碼中聲明。它們用於在編譯或運行時分析代碼。您可以將註釋視為標籤、標籤或編譯器提示。

您之前可能遇到過註釋。比如重寫父類的一個方法,我們在方法本身之前寫上@Override 。該註解表明父類的方法將在子類中被覆蓋。

句法:


@Override
public int hashCode() {
      return super.hashCode();
}

我想立即指出註釋不僅僅適用於方法。它們與包、類、方法、字段和參數一起使用。

要了解註釋的工作原理,首先讓我們熟悉標記接口的概念。自 Java 出現以來,開發人員一直需要一種方法來標記類,以便對它們執行某些操作。

在 Java 5 之前,他們使用的接口不符合我們期望的接口功能。它沒有方法,也沒有契約。它只是以某種方式將一個類標記為特殊的。

這樣的接口被稱為標記接口。從名字你可能猜到它的目的是為 JVM、編譯器或一些庫標記類。保留了一些標記接口,例如Serializable。這個標記接口讓我們表明一個類的實例可以被序列化。

正如我們所見,即使在引入註解之後,標記接口仍然存在。

註釋與標記接口:


@MyAnnotation
public class MyClass {}

public class MyClass implements MarkerInterface {}

兩種方法都有相同的目標,但它們的實現有明顯的區別。例如,考慮一個接口和一個指示類屬於特定類型的註釋。

如果我們正在使用一個接口,那麼我們就標記這個類。如果我們使用不當,出現錯誤,那麼我們會在編譯時發現問題,程序將無法運行。

有了註解,一切就不那麼簡單了:這裡會在運行時檢測到錯誤,這意味著程序會啟動,但不出所料,它不會完成。

請注意,如果我們需要標記一個類以供將來使用,則必須將其實例傳遞給特定方法:


public class MyInteger implements Sum {}
interface Sum {};

public static void main(String[] args) throws IOException {
        increase(new MyInteger());
}
 
public static void increase(Sum count) {
        // TODO
}

標記界面在這裡效果最好。

當我們需要更多東西的時候最好使用註解,比如註解支持的參數。

我們來看看JDK中的標準註解:

註解 描述 例子
@覆蓋 指定方法覆蓋超類的方法或實現抽像類或接口的方法。

@Override
public int hashCode() {
        return super.hashCode();
}
@棄用 將代碼標記為已棄用。

@Deprecated
public abstract void method();
@SuppressWarnings 為帶註釋的元素禁用編譯器警告。請注意,如果您需要禁用多個類別的警告,則必須將它們括在花括號中,例如@SuppressWarnings({"unchecked", "cast"})

public class DocumentsFolder {
   private List documents;

   @SuppressWarnings("unchecked")
public void addDocument(String document) {
            documents.add(document);
   }
}

在這個例子中,我們試圖添加到一個沒有定義類型(泛型)的列表中。編譯器會警告我們這一點。這非常有用,但有時“警告”太多,它們可能會很吵。您可以使用此方法註釋並將編譯器警告類型指定為參數。有很多標記,所以不用擔心全部記住它們——IDEA 通常會告訴您要添加哪一個。

另一個有多個參數的例子:


@SuppressWarnings({"unchecked", "deprecated"})