以前介紹繼承的時候,提到對於子類而言,父類的普通方法能夠重寫也能夠不重寫,可是父類的抽象方法是必須重寫的,若是不重寫,編譯器就直接在子類名稱那裏顯示紅叉報錯。例如,之前演示抽象類用法之時,曾經把Chicken雞類的call方法改成抽象方法,方法聲明代碼以下所示:html
// 定義一個抽象的叫喚方法。注意後面沒有花括號,而且以分號結尾 abstract public void call();
假若派生自雞類的公雞類沒有重寫call方法,編譯器除了紅叉報錯之外,還會彈出提示「Add unimplemented method」,也就是建議開發者爲公雞類補充實現call方法。按照建議點擊提示文字,eclipse會自動在公雞類中添加如下的默認代碼:java
@Override public void call() { // TODO Auto-generated method stub }
注意到新增的call方法上面一行,多出了形如「@Override」的標記,該標記看起來彷佛是多餘的,即便把它刪掉,編譯器也不會報錯,程序也能正常運行。莫非「@Override」是另外一種形式的註釋?實際上,以@符號開頭的標記,它們的真正名稱叫作「註解」,跟「註釋」僅有一字之差,兩者的關係恰如名字那樣,既有相同點又有不一樣點。相同點爲:註解同樣帶有解釋說明的涵義,好比Override翻譯成中文就是「重寫」的意思,表示標記下方的call方法重寫了父類的抽象方法。不一樣點爲:註釋是給人看的,而註解還要給編譯器看,編譯器掃描到註解@Override,便會去檢查父類是否存在註解下方的方法聲明,若是不存在或者參數類型對不上,就會提示紅叉錯誤。
除了方法重寫註解「@Override」以外,還有一種常見的註解叫「@FunctionalInterface」,翻譯成中文即是「函數式接口」,猜的沒錯,該註解專門用來標記Java8規定的函數式接口。函數式接口是一類特殊的接口形式,它的內部有且僅有一個抽象方法,抽象方法多了不行,再來一個抽象方法的話,接口實例就無法簡寫爲Lambda表達式,也就沒法成爲「函數式」接口。Java自帶的幾個函數式接口包括:比較器Comparator、斷言接口Predicate、消費接口Consumer、函數接口Function、文件過濾器FileFilter、運行器Runnable等等,查看它們的源碼,會發現接口定義的上方無一例外都存在註解「@FunctionalInterface」。例以下面是比較器Comparator的核心定義代碼:程序員
//該註解表示如下定義的是函數式接口,有且僅有一個抽象方法聲明。 //若是同時聲明瞭多個抽象方法,則編譯器在編碼階段就會報錯。 @FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); // 此處省略比較器接口的剩餘代碼定義 }
@FunctionalInterface註解明白無誤地告訴編譯器,它的下方接口是個函數式接口,請務必檢查這個接口定義是否符合函數式接口的要求。編譯器根據註解的指示,當即掃描註解下方的接口代碼,並仔細統計接口內部的抽象方法個數,假若抽象方法的數量不足一個或者多於一個,編譯器都會提示錯誤「Invalid '@FunctionalInterface' annotation; *** is not a functional interface」,意思是「註解@FunctionalInterface是無效的,由於***不是一個函數式接口」,這樣正好提醒開發者檢查接口定義是否存在問題。
第三種常見的註解名叫「@Deprecated」,早前介紹日期工具Date的時候,在代碼中調用日期實例的getYear、getMonth、getDate等方法,這幾個方法的名稱中間竟然出現了一條刪除線。查看相關日期方法的源碼,才發覺它們的定義代碼上方聳立着註解「@Deprecated」,該註解的含義是「不同意、已廢棄」,原因是Java認爲這幾個日期方法已通過時了,隨時都會從開發包中移除,建議開發者將它們替換成日曆工具裏的對應方法。儘管目前仍然能夠在代碼中調用這些過期的方法,可是編譯器依舊按照規定在方法名稱中間顯示刪除線,而且還會給出警告「Add @SupressWarnings 'deprecated' to '***'」。這警告說的是建議往***添加註解「@SupressWarnings」(含義爲屏蔽警告),從而避免此處的警告提示。正所謂「眼不見心不煩」,那就按照建議在日期方法的調用處通通添加新註解「@SuppressWarnings("deprecation")」,添加完了,果真這些「已過期」的警告都被屏蔽掉了。
註解@SuppressWarnings不只可用來屏蔽「已過期」的警告,還能用來屏蔽其它類型的警告,譬如「未使用」這類警告。上一篇文章演示私有方法的反射調用之時,給Chicken類增長了setName、getName、setSex、getSex四個私有方法,這些方法並未被Chicken類自身所調用,編譯器會認爲它們是「未使用」的方法,於是在這四個方法的定義處提示警告信息「Remove method '***'」,也就是建議刪除某某某方法。若是程序員仍想保留這些方法,又不想看到警告提示,則可在Chicken類上方添加註解「@SuppressWarnings("unused")」,表示屏蔽未使用的警告。添加了@SuppressWarnings註解的雞類定義代碼片斷示例以下:安全
//該註解表示屏蔽「未使用」這種警告 @SuppressWarnings("unused") abstract public class Chicken { // 此處省略雞類的其它代碼定義 private void setName(String name) { // 設置名稱 this.name = name; } private String getName() { // 獲取名稱 return this.name; } private void setSex(int sex) { // 設置性別 this.sex = sex; } private int getSex() { // 獲取性別 return this.sex; } }
上面的四種註解中,@Override、@Deprecated、@SuppressWarnings這三種是從Java5開始引入的,而@FunctionalInterface是在Java8才引入的。除此以外,Java7還引入了第五種註解名叫「@SafeVarargs」,主要目的是兼容可變參數中的泛型參數,該註解告訴編譯器:此處可變參數中的泛型是類型安全的,沒必要擔憂強制類型轉換的問題。因爲前述的五種註解是系統提供給開發者使用的,所以它們被統稱爲「內置註解」。eclipse
更多Java技術文章參見《Java開發筆記(序)章節目錄》ide