什麼是 Annotation? (註解 or 注釋)
Annotation, 準確的翻譯應該是 -- 註解。 和注釋的作用完全不一樣。
Annotation 是JDK5.0及以後版本引入的一個特性。 與類、介面、枚舉是在同一個層次,可以成為java 的一個類型。
文法是以@ 開頭
簡單來說,
注釋是程式員對原始碼的類,方法,屬性等做的一些記憶或提示性描述(比如這個方法是做什麼用的),是給人來看的。
註解則是Java 編譯器可以理解的部分,是給編譯器看的。
舉個簡單的例子來看一下註解的使用和作用。
@Override 是比較常見的Java 內建註解,它的作用就是在編譯代碼的時候檢查子類中定義的方法是否正確。
package annotation;public abstract class Animal {public abstract void eat();}
package annotation;public class Cat extends Animal{@Overridepublic void eat(String food) {}}
這裡在子類Cat中 eat 方法被註解為覆寫父類的方法, 但是卻比父類方法多出一個參數。
如果是在Eclipse 在編輯的話, 直接就會有紅色叉叉提示。(代碼編譯會通不過)。
如果去掉@Override的註解的話, 編譯沒問題, 但是Cat 中eat方法就是這個類的一個新的方法了,而不是從父類繼承的了。
常見的Java 內建註解
包含@Override , 還有哪些常見的Java內建註解?
1. @Deprecated
註解為不建議使用,可以用在 方法和類上。
基本上這種方法和類都是因為升級或效能上面的一些原因廢棄不建議使用,但是為了相容或其他原因,還必須保留。
所以就打上這個註解。
在Java 本身的API中就有很多這樣的例子, 方法打上了這個註解,進到Source code 會看到替代的新的方法是哪個。
在eclipse 中編寫code時,添加此註解的方法在聲明和調用的地方都會加上刪除線。
2.@Override
3.@SuppressWarnings
忽略警告。
如果你的code在轉型或其他的部分有一些警告的話,但是你又想忽略這些警告,就可以使用這個註解了。
1)deprecation 使用了不贊成使用的類或方法時的警告
2)unchecked 執行了未檢查的轉換時警告
3)fallthrough 當使用switch操作時case後未加入break操作,而導致程式繼續執行其他case語句時出現的警告
4)path 當設定一個錯誤的類路徑、源檔案路徑時出現的警告
5)serial 當在可序列化的類上缺少serialVersionUID定義時的警告
6)fianally 任何finally子句不能正常完成時警告
7)all 關於以上所有情況的警告
自訂註解
除了Java本身提供的內建註解, Java 還提供了定製自訂註解的功能。
定義的方式就是使用註解定義註解, 用來定義註解的註解稱為元註解。
主要的元註解有以下四個:@Target ;@Retention;@Documented;@Inherited
1. @Target 表示該註解用於什麼地方,使用在類上,方法上,或是屬性等
可能的 ElemenetType 參數包括:
ElemenetType.CONSTRUCTOR 構造器聲明
ElemenetType.FIELD 域聲明(包括 enum 執行個體)
ElemenetType.LOCAL_VARIABLE 局部變數聲明
ElemenetType.METHOD 方法聲明
ElemenetType.PACKAGE 包聲明
ElemenetType.PARAMETER 參數聲明
ElemenetType.TYPE 類,介面(包括註解類型)或enum聲明
2. @Retention 表示在什麼層級儲存該註解資訊
可選的 RetentionPolicy 參數包括:
RetentionPolicy.SOURCE 註解將被編譯器丟棄
RetentionPolicy.CLASS 註解在class檔案中可用,但會被VM丟棄
RetentionPolicy.RUNTIME VM將在運行期也保留注釋,因此可以通過反射機制讀取註解的資訊。
3. @Documented ,產生doc時,是否包含此註解
將此註解包含在 javadoc 中
4. @Inherited
允許子類繼承父類中的註解
看一些簡單定義的例子:
package annotation;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Inherited;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Target(ElementType.METHOD)public @interface MyAnnotation {String value();}@Retention(RetentionPolicy.SOURCE) @interface MyAnnotation1 { } @Retention(RetentionPolicy.CLASS) @interface MyAnnotation2 {} @Retention(RetentionPolicy.RUNTIME) @interface MyAnnotation3 {}@Documented@interface MyAnnotation4 {} @Inherited@interface MyAnnotation5 { }
使用例子:
package annotation;import java.lang.annotation.Annotation;@MyAnnotation3public class TestAnnotation {public static void main(String[] args) {// TODO Auto-generated method stubAnnotation annotation = TestAnnotation.class.getAnnotation(MyAnnotation3.class);System.out.println(annotation.toString());}}
列印出結果: @annotation.MyAnnotation3()
以上例子如果替換使用 MyAnnotation1 和 MyAnnotation2 的話, 則取到的annotation的值為空白,這就是RetentionPolicy 不同的差別。
Annotation的作用
介紹到此,可以總結一下Annotation的作用了。
基礎的大致可以分為三類:
1. 編寫文檔
2. 程式碼分析
3. 編譯檢查但是,開源架構對其賦予了更多的作用
比如:
Hibernate,註解配置,
@Column("aa")private String xx;
這個類似於XML配置,簡化程式中的配置
相對與把一部分中繼資料從XML檔案移到了代碼本身之中,在一個地方管理和維護。
內部如何?的? -- java 反射機制,類似與以上例子。