1. 程式人生 > >[01] 註解的基本認識和元註解

[01] 註解的基本認識和元註解

ons 方法 ide 參考 ive img 重寫 列表 bject


1、什麽是註解

技術分享用一個詞就可以描述註解,那就是元數據,即一種描述數據的數據。所以,可以說註解就是源代碼的元數據。

  1. @Override
  2. public String toString() {
  3. return "This is String Representation of current object.";
  4. }
如上代碼,重寫了toString()方法並使用了@Override註解。但是,即使不使用@Override註解標記代碼,程序也能夠正常執行。那麽,該註解表示什麽?有什麽好處?
事實上,@Override告訴編譯器這個方法是一個重寫方法(描述方法的元數據),如果父類中不存在該方法,編譯器便會報錯,提示該方法沒有重寫父類中的方法。如果我不小心拼寫錯誤,例如將toString()寫成了toStrring(),而且我也沒有使用@Override註解,那程序依然能編譯運行,但運行結果會和我期望的大不相同。


2、註解的意義

在進行Java程序開發的時候,免不了和各種配置文件打交道,以經典的框架Spring或者Hibernate來說,不論是IOC的bean配置,還是持久化的ORM映射關系配置,都有各自的xml格式的配置文件。
這些配置文件都必須與Java代碼同步,否則的話就會出現問題。然而把同一份信息保存在兩個地方,並不是一個好的主意,因為維護隨著代碼量會越來越繁瑣,理想的情況下把配置信息和代碼都在同一個地方維護就好了。
JDK5中引入了註解機制,它類似於代碼中的註釋,不同的是註解不是提供代碼功能的說明,而是實現程序功能的重要組成部分。在Spring或者Hibernate等主流框架中我們已經可以看到,已經開始可以使用註解的方式來替代xml配置文件,達到簡化程序配置的目的。

3、元註解

元註解的作用就是負責註解其他註解
Java5.0定義了4個標準的meta-annotation類型,它們被用來提供對其他annotation類型作說明:
  • @Target 註解用於什麽地方
  • @Retention 註解類型的存活時間
  • @Documented 註解是否包含在JavaDoc中
  • @Inherited 是否允許子類繼承該註解

3.1 @Target

@Target 說明了Annotation所修飾的範圍,表示該註解用於什麽地方,如果不明確指出,該註解可以放在任何地方:
  • packages
  • types(類、接口、枚舉、Annotation類型)
  • 類型成員(方法、構造方法、成員變量、枚舉值)
  • 方法參數和本地變量(如循環變量、catch參數)


以下是一些可用的參數
  • ElementType.TYPE (描述類、接口、註解、或者枚舉)
  • ElementType.FIELD (描述實例變量)
  • ElementType.METHOD (描述方法)
  • ElementType.PARAMETER (描述參數)
  • ElementType.CONSTRUCTOR (描述構造方法)
  • ElementType.LOCAL_VARIABLE (描述局部變量)
  • ElementType.ANNOTATION_TYPE (描述另一個註解)
  • ElementType.PACKAGE (描述包)

示例:(1)註解Table可以用於註解類、接口(包括註解類型) 或enum聲明(2)註解NoDBColumn僅可用於註解類的成員變量
  1. @Target(ElementType.TYPE)
  2. public @interface Table {
  3. /**
  4. * 數據表名稱註解,默認值為類名稱
  5. * @return
  6. */
  7. public String tableName() default "className";
  8. }
  9. @Target(ElementType.FIELD)
  10. public @interface NoDBColumn {
  11. }

3.2 @Retention

某些Annotation僅出現在源代碼中,而被編譯器丟棄;而另一些卻被編譯在class文件中;編譯在class文件中的Annotation可能會被虛擬機忽略,而另一些在class被裝載時將被讀取(請註意並不影響class的執行,因為Annotation與class在使用上是被分離的)。
使用這個meta-Annotation可以對Annotation的“生命周期”限制,即@Retention定義了該Annotation被保留的時間長短
以下是一些可用的參數:
  • RetentionPoicy.SOURCE (源文件中有效,即源文件保留)
  • RetentionPoicy.CLASS (class文件中有效,即class保留)
  • RetentionPoicy.RUNTIME (運行時有效,即運行時保留)

示例:(1)Column註解的的RetentionPolicy的屬性值是RUNTIME,這樣註解處理器可以通過反射,獲取到該註解的屬性值,從而去做一些運行時的邏輯處理(2)@Column是個修飾屬性的,在運行時有效的註解
  1. @Target(ElementType.FIELD)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. public @interface Column {
  4. public String name() default "fieldName";
  5. public String setFuncName() default "setField";
  6. public String getFuncName() default "getField";
  7. public boolean defaultDBValue() default false;
  8. }

3.3 @Documented

該註解用於描述其它類型的annotation應該被作為被標註的程序成員的公共API,因此可以被例如javadoc此類的工具文檔化。Documented是一個標記註解,沒有成員

3.4 @Inherited

該註解是一個標記註解,闡述了某個被標註的類型是被繼承的。如果一個使用了@Inherited修飾的annotation類型被用於一個class,則這個annotation將被用於該class的子類。


4、參考鏈接

  • 深入理解Java:註解(Annotation)自定義註解入門

附件列表

  • 25200814-475cf2f3a8d24e0bb3b4c442a4b44734.jpg

[01] 註解的基本認識和元註解