Java程式設計師需要掌握的5個註解
@Override
@FunctionalInterface
@SuppressWarnings
@SafeVarargs
@Deprecated
首先,我們將深入研究Java中最常用的註解之一:@Override。
一、 @Override
覆蓋方法的實現或為抽象方法提供實現的能力是任何面向物件(OO)語言的核心。由於Java是OO語言,具有許多常見的面向物件的抽象機制,所以在非終極超類定義的非最終方法或介面中的任何方法(介面方法不能是最終的)都可以被子類覆蓋
二、 @FunctionalInterface
隨著JDK 8中lambda表示式的引入,函式式介面在Java中變得越來越流行。這些特殊型別的介面可以用lambda表示式、方法引用或建構函式引用代替。根據@FunctionalInterface文件,函式式介面的定義如下:
一個函式式介面只有一個抽象方法。由於預設方法有一個實現,所以它們不是抽象的。
例如,以下介面被視為函式式介面:
public interface Foo { public int doSomething();}public interface Bar { public int doSomething(); public default int doSomethingElse() { return 1; }}
三、 @SuppressWarnings
警告是所有編譯器的重要組成部分,為開發人員提供的反饋——可能危險的行為或在未來的編譯器版本中可能會出現的錯誤。例如,在Java中使用泛型型別而沒有其關聯的正式泛型引數(稱為原始型別)會導致警告,就像使用不推薦使用的程式碼一樣(請參閱下面的@Deprecated部分)。雖然這些警告很重要,但它們可能並不總是適用甚至並不總是正確的。例如,可能會有對不安全的型別轉換髮生警告的情況,但是基於使用它的上下文,我們可以保證它是安全的。
四、 @SafeVarargs
可變引數在Java中是一種很有用的技術手段,但在與泛型引數一起使用時,它們也可能會導致一些嚴重的問題。由於泛型在Java中是非特定的,所以具有泛型型別的變數的實際(實現)型別不能在執行時被斷定。由於無法做出此判斷,因此變數可能會儲存非其實際型別的引用到型別,如以下程式碼片段所示(摘自《Java
Generics FAQs》):
List ln = new ArrayList();ln.add(1);List ls = ln; // unchecked warning String s = ls.get(0); // ClassCastException
在將ln分配給ls後,堆中存在變數ls,該變數具有List的型別,但儲存引用到實際為List型別的值。這個無效的引用被稱為堆汙染。由於直到執行時才能確定此錯誤,因此它會在編譯時顯示為警告,並在執行時出現ClassCastException。當泛型引數與可變引數組合時,可能會加劇此問題:
public class Foo { public void doSomething(T... args) { // ... }}
五、 @Deprecated
在開發程式碼時,有時候程式碼會變得過時和不應該再被使用。在這些情況下,通常會有個替補的更適合手頭的任務,且雖然現存的對過時程式碼的呼叫可能會保留,但是所有新的呼叫都應該使用替換方法。這個過時的程式碼被稱為不推薦使用的程式碼。在某些緊急情況下,不建議使用的程式碼可能會被刪除,應該在未來的框架或庫版本從其程式碼庫中刪除棄用的程式碼之前立即轉換為替換程式碼。
為了支援不推薦使用的程式碼的文件,Java包含@Deprecated註解,它會將一些建構函式、域、區域性變數、方法、軟體包、模組、引數或型別標記為已棄用。如果棄用的元素(建構函式,域,區域性變數等)被使用了,則編譯器發出警告。例如,我們可以建立一個棄用的類並按如下所示使用它:
@Deprecatedpublic class Foo {}Foo foo = new Foo();
如果我們編譯此程式碼(在命名為Main.java的檔案中),我們會收到以下警告:
$ javac Main.javaNote: Main.java uses or overrides a deprecated API.Note: Recompile with -Xlint:deprecation for details.
通常,每當使用@Deprecated註解的元素時,都會引發警告,除了用於以下五種情況:
宣告本身就被宣告為是棄用的(即遞迴呼叫)。
宣告被註解禁止棄用警告(即@SuppressWarnings(“deprecation”)註解,如上所述,應用於使用棄用元素的上下文。
使用和宣告都在同一個最外面的類中(即,如果類呼叫其本身的棄用方法)。
用在import宣告中,該宣告匯入通常不贊成使用的型別或構件(即,在將已棄用的類匯入另一個類時)。
exports或opens指令內