1. 程式人生 > >Java註釋Override Deprecated SuppressWarnings詳解

Java註釋Override Deprecated SuppressWarnings詳解

四、如何對註釋進行註釋     這一節的題目讀起來雖然有些繞口,但它所蘊涵的知識卻對設計更強大的java程式有很大幫助。 在上一節討論了自定義註釋,由此我們可知註釋在J2SE5.0中也和類、介面一樣。是程式中的一個基本的組成部分。既然可以對類、介面進行註釋,那麼當然也可以對註釋進行註釋。    使用普通註釋對註釋進行註釋的方法和對類、介面進行註釋的方法一樣。所不同的是,J2SE5.0為註釋單獨提供了4種註釋。它們是Target、Retention、Documented和Inherited。下面就分別介紹這4種註釋。   Target    這個註釋理解起來非常簡單。由於target的中文意思是“目標”,因此,我們可能已經猜到這個註釋和某一些目標相關。那麼這些目標是指什麼呢?大家可以先看看下面的程式碼。@Target(
ElementType.METHOD)            @interface MyAnnotation {}                        @MyAnnotation // 錯誤的使用            publicclass Class1            {            @MyAnnotation // 正確的使用            publicvoid myMethod1() {}            }                以上程式碼定義了一個註釋MyAnnotation和一個類Class1,並且使用MyAnnotation分別對Class1和myMethod1進行註釋。如果編譯這段程式碼是無法通過的。也許有些人感到驚訝,沒錯啊!但問題就出在@Target(ElementType.METHOD)上,由於Target使用了一個列舉型別屬性,它的值是ElementType.METHOD。這就表明MyAnnotation只能為方法註釋。而不能為其它的任何語言元素進行註釋。因此,MyAnnotation自然也不能為Class1進行註釋了。   說到這,大家可能已經基本明白了。原來target所指的目標就是java的語言元素。如類、介面、方法等。當然,Target還可以對其它的語言元素進行限制,如建構函式、欄位、引數等。如只允許對方法和建構函式進行註釋可以寫成:@Target(
{ElementType.METHOD, ElementType.CONSTRUCTOR})            @interface MyAnnotation {}                        Retention      既然可以自定義註釋,當然也可以讀取程式中的註釋(如何讀取註釋將在下一節中討論)。但是註釋只有被儲存在class檔案中才可以被讀出來。而Retention就是為設定註釋是否儲存在class檔案中而存在的。下面的程式碼是Retention的詳細用法。@Retention(RetentionPolicy.SOURCE)            @interface MyAnnotation1
{ }                        @Retention(RetentionPolicy.CLASS)            @interface MyAnnotation2 {}                        @Retention(RetentionPolicy.RUNTIME)            @interface MyAnnotation3 {}                其中第一段程式碼的作用是不將註釋儲存在class檔案中,也就是說象“//”一樣在編譯時被過濾掉了。第二段程式碼的作用是隻將註釋儲存在class檔案中,而使用反射讀取註釋時忽略這些註釋。第三段程式碼的作用是即將註釋儲存在class檔案中,也可以通過反射讀取註釋。Documented     這個註釋和它的名子一樣和文件有關。在預設的情況下在使用javadoc自動生成文件時,註釋將被忽略掉。如果想在文件中也包含註釋,必須使用Documented為文件註釋。@interface MyAnnotation{ }            @MyAnnotation            class Class1            {            publicvoid myMethod() { }            }            使用javadoc為這段程式碼生成文件時並不將@MyAnnotation包含進去。生成的文件對Class1的描述如下: class Class1extends java.lang.Object            而如果這樣定義MyAnnotation將會出現另一個結果。            @Documented            @interface MyAnnotation {}                        生成的文件:            @MyAnnotation // 這行是在加上@Documented後被加上的            class Class1extends java.lang.Object                        Inherited     繼承是java主要的特性之一。在類中的protected和public成員都將會被子類繼承,但是父類的註釋會不會被子類繼承呢?很遺憾的告訴大家,在預設的情況下,父類的註釋並不會被子類繼承。如果要繼承,就必須加上Inherited註釋。@Inherited            @interface MyAnnotation { }                        @MyAnnotation            publicclass ParentClass {}            publicclass ChildClass extends ParentClass { }                        在以上程式碼中ChildClass和ParentClass一樣都已被MyAnnotation註釋了。            

五、如何使用反射讀取註釋     前面討論瞭如何自定義註釋。但是自定義了註釋又有什麼用呢?這個問題才是J2SE5.0提供註釋的關鍵。自定義註釋當然是要用的。那麼如何用呢?解決這個問題就需要使用java最令人興奮的功能之一:反射(reflect)。在以前的JDK版本中,我們可以使用反射得到類的方法、方法的引數以及其它的類成員等資訊。那麼在J2SE5.0中同樣也可以象方法一樣得到註釋的各種資訊。     在使用反射之前必須使用import java.lang.reflect.* 來匯入和反射相關的類。     如果要得到某一個類或介面的註釋資訊,可以使用如下程式碼: Annotation annotation = TestAnnotation.class.getAnnotation(MyAnnotation.class);如果要得到全部的註釋資訊可使用如下語句:Annotation[] annotations = TestAnnotation.class.getAnnotations();或Annotation[] annotations = TestAnnotation.class.getDeclaredAnnotations();getDeclaredAnnotations與getAnnotations類似,但它們不同的是getDeclaredAnnotations得到的是當前成員所有的註釋,不包括繼承的。而getAnnotations得到的是包括繼承的所有註釋。    如果要得到其它成員的註釋,可先得到這個成員,然後再得到相應的註釋。如得到myMethod的註釋。

Method method = TestAnnotation.class.getMethod("myMethod", null);            Annotation annotation = method.getAnnotation(MyAnnotation.class);            注:要想使用反射得到註釋資訊,這個註釋必須使用            @Retention(RetentionPolicy.RUNTIME)進行註釋。                       

總結     註釋是J2SE5.0提供的一項非常有趣的功能。它不但有趣,而且還非常有用。EJB3規範就是藉助於註釋實現的。這樣將使EJB3在實現起來更簡單,更人性化。還有Hibernate3除了使用傳統的方法生成hibernate對映外,也可以使用註釋來生成hibernate對映。總之,如果能將註釋靈活應用到程式中,將會使你的程式更加簡潔和強大。