說起注解語法,對於任何一個Java開發人員來說都已經耳熟能詳了,我們每天都在使用著 @author, @param,等等編寫注釋,然後用javadoc生成文檔。Java的這種方便的文檔生成方法受到了開發者的普遍贊譽。而從JDK1.5開始,注釋語法提供了更為強大的功能。
我們先談談注釋語法本身,它有時候也稱為meta-data :“描述數據的數據” 。一般來說它們可以被用來生成文檔,檢查代碼間依賴關系,幫助編譯器作語法檢查。時下比較流行的工具有Xdoclet等。對於文檔生成早已經有了javadoc工具的完美表現,而對於代碼檢查,如今java也提供了語言級的支持。
我們知道,javadoc是通過提取java源文件中的標簽信息來生成文檔。所以要學習新的注釋語法,們首先要熟悉的就是新增的標簽。新的注釋語法支持兩種標簽,系統標准標簽和用戶自定義標簽。標簽的符號也原先一樣,@符號加上標簽名字。我們先從JDK1.5自帶的標准標簽說起。
首先介紹@override , 也不用多羅嗦,顧名思義了,就是用來說明方法覆載的。我們假設有一個子類必須要覆載父類的方法.
public class Parent{
public void foo(){
System.out.println("Original Implementation of foo");
}
}
public class Child extends Parent{
@Override
public void foo(){
System.out.println("Overide Implementation of foo");
}
}
目前為止我們看不出來這個@Override給我們帶來了任何好處,所以我們先說說加個這個標簽後,我們用javac編譯的時候編譯器執行了些什麼呢?編譯器會檢查這個方法,然後從父類查找是否有這個方法,否則就編譯出錯。這個特性可以幫助我們避免一些低級錯誤。上面這個例子,子類想覆載foo()方法,不過你可能一時疏忽把它寫成了fob(), 對於這樣的”低級錯誤”,如果你沒有在前期就發現的話,到系統集成測試的時候,可能會化上你幾個小時甚至一兩天去找出這樣的bug。現在好了,編譯器在編譯的時候就會給出錯誤,
Child.java:3: method does not override a method from its superclass
@Override
^
1 error
怎麼樣,這個功能還不錯吧。
看過了標准標簽的使用方法,我們來看看用戶自定義標簽。首先介紹@interface, 它用於定義新的注釋類型(annotation type)。新建一個注釋類型看起來和定義一Interface 沒有什麼兩樣,MyTag.java用於新建一個用戶自定義標簽,代碼如下,
package tiger.annotation;
/**
* 用戶自定義標簽??MyTag
*/
public @interface MyTag { }
定義了一個tag之後,我們就可以在任何java文件中使用這個tag了,
import tiger.annotation.MyTag;
public class TagTest{
@MyTag
public void testTag(){
}
}
注釋類型還可以有成員變量,
package tiger.annotation;
/**
* 用戶自定義標簽??帶有成員變量的MyTag
*/
public @interface MyTag {
String name();
int age();
}
然後我們可以這麼使用這個標簽,
@MyTag(name="MyTag",age=1)
public void testTag(){
}
使用標簽最終是為了幫助開發人員提取注釋信息,然後根據不同需求做進一步處理,下面我們來看看如何獲取注釋信息。
import java.lang.annotation.Annotation;
import tiger.annotation.MyTag;
public class TagTest{
@MyTag(name="MyTag",age=1)
public void test(){
}
public static void main(String[] args){
TagTest tt = new TagTest();
try {
Annotation[] annotation =tt.getClass().getMethod("test").getAnnotations();
for (Annotation tag :annotation) {
System.out.println("Tag is:" + tag);
System.out.println("tag.name()" + ((MyTag)tag).name());
System.out.println("tag.age()" + ((MyTag)(tag)).age());
}
} catch(NoSuchMethodException e) {
e.printStackTrace();
}
}
}
需要注意的一點是,在執行這段代碼之前我們還有一點小工作要做,還需要給我們的自定義標簽MyTag加上一個說明標簽,@ Retention, 表明注釋信息將可以在運行時刻通過反射機制得到。如果不加入這個標簽,上面的代碼將沒有任何輸出。修改以後的MyTag如下:
/**
* 用戶自定義標簽??帶有成員變量的MyTag
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTag {
String name();
int age();
}
然後我們執行TagTest可以得到輸出如下,
Tag is:@tiger.annotation.MyTag(name=MyTag, age=1)
tag.name()MyTag
tag.age()1
好了,Tiger新的注釋語法基本用法就這麼簡單,基本用法雖然簡單,但是獲取注釋信息之後如何處理確很值得推敲,我們可以用他們來做一些語法檢查,文件相關性檢查,進行各種統計等等。關於更多的Tiger新注釋語法的信息,可以訪問[link=http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html]。
以上代碼在win2k + j2se5 GA下通過。