Java Annotation自訂註解詳解__Java

來源:互聯網
上載者:User

在開發過程中總能用到註解,但是從來沒有自己定義過註解。最近賦閑在家,研究整理了一番,力求知其然知其所以然。

本文會嘗試描述什麼是註解,以及通過一個Demo來說明如何在程式中自訂註解。Demo沒有實際意義,僅僅只是為了註解而使用註解。

 

1、什麼是註解。

       註解是在jdk 1.5開始提供的功能,目前被廣泛使用。以下是引用《Java瘋狂講義》第十四章關於註解的描述:

       “Annotation其實是代碼裡的特殊標記,這些標記可以在編譯、類載入、運行時被讀取,並執行響應的處理。通過使用Annotation,程式開發人員可以在不改變原有邏輯的情況下,在源檔案嵌入一些補充資訊。程式碼分析工具、開發工具和部署工具可以通過這些補充資訊進行驗證或者進行部署。”

      

       JUnit單元測試就是基於註解的。我認為使用動態代理和註解,自己完全也可以寫一個MyJUnit。

      

2、Demo的實現:

註解檔案:

這個檔案主要包含了三個部分:

       A.註解檔案使用@interface來聲明。

       B.在A外層有元註解聲明(註解的註解),主要的作用就是對我們自訂註解的執行範圍、時期進聲明。下面是註解的註解含義說明:

@Documented:指示某一類型的注釋將通過 javadoc 和類似的預設工具進行文檔化。應使用此類型來注釋這些類型的聲明:其注釋會影響由其用戶端注釋的元素的使用。如果型別宣告是用 Documented 來注釋的,則其注釋將成為注釋元素的公用 API 的一部分。

@Target:指示注釋類型所適用的程式元素的種類。如果注釋型別宣告中不存在 Target 元注釋,則聲明的類型可以用在任一程式元素上。如果存在這樣的元注釋,則編譯器強制實施指定的使用限制。例如,此元注釋指示該宣告類型是其自身,即元注釋類型。它只能用在注釋型別宣告上。

@Inherited:指示注釋類型被自動繼承。如果在注釋型別宣告中存在 Inherited 元注釋,並且使用者在某一類聲明中查詢該注釋類型,同時該類聲明中沒有此類型的注釋,則將在該類的超類中自動查詢該注釋類型。此過程會重複進行,直到找到此類型的注釋或到達了該類階層的頂層 (Object) 為止。如果沒有超類具有該類型的注釋,則查詢將指示當前類沒有這樣的注釋。注意,如果使用注釋類型注釋類以外的任何事物,此元注釋類型都是無效的。還要注意,此元注釋僅促成從超類繼承注釋;對已實現介面的注釋無效。

@Retention:指示注釋類型的注釋要保留多久。如果注釋型別宣告中不存在 Retention 注釋,則保留原則預設為 RetentionPolicy.CLASS。

C.方法名就是參數名,傳回值類型就是參數的類型,通過default來設定方法的預設值。

 

下面是代碼:

package com.array7.annotationTest;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;@Documented@Target(ElementType.METHOD)@Inherited@Retention(RetentionPolicy.RUNTIME)public @interface MethodInfo {String author() default "array7";// 作者String date();// 日期double version() default 1.0;// 版本號碼String comments();// 注釋}

然後定義個調用註解的類:

package com.array7.annotationTest;public class AnnotationExample {/** * 非靜態方法 * @param msg */@MethodInfo(author = "七郎", comments = "方法測試注釋:print10", date = "2013-11-29", version = 1.0)public void print10(Object msg) {System.out.println(msg);}/** * 靜態方法 */@MethodInfo(author = "七郎", comments = "方法測試注釋:print20", date = "2013-11-20", version = 2.0)public static void print20() {System.out.println("test");}}

最後就是註解解析類(簡單起見我將代碼寫在了main方法裡):


package com.array7.annotationTest;import java.lang.annotation.Annotation;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class AnnotationParsing {public static void main(String[] args) {try {Class<?> clazz = Class.forName("com.array7.annotationTest.AnnotationExample");// 這裡可以封裝成動態代理類。// Class clazz = AnnotationParsing.class.getClassLoader().loadClass("com.array7.annotationTest.AnnotationExample");// 這種方式也OK。for (Method method : clazz.getMethods()) {if (method.isAnnotationPresent(MethodInfo.class)) {for (Annotation anno : method.getAnnotations()) {System.out.println("Annotation in Method [" + method + "]:" + anno);MethodInfo methodInfo = method.getAnnotation(MethodInfo.class);if (methodInfo.version() == 1.0) {method.invoke(clazz.newInstance(), methodInfo.comments());} else if (methodInfo.version() == 2.0) {method.invoke(null);}}}}} catch (SecurityException e) {e.printStackTrace();} catch (ClassNotFoundException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (InstantiationException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}


程式最後輸出:

Annotation in Method [public void com.array7.annotationTest.AnnotationExample.print10(java.lang.Object)]:@com.array7.annotationTest.MethodInfo(author=七郎, version=1.0, comments=方法測試注釋, date=2013-11-20)方法測試注釋Annotation in Method [public static void com.array7.annotationTest.AnnotationExample.print20()]:@com.array7.annotationTest.MethodInfo(author=七郎, version=2.0, comments=方法測試注釋, date=2013-11-20)test

通過上述輸出我們也可以發現,註解有限執行的是執行個體化之後的方法,然後才是靜態方法。

  上面所提到的知識理論和實踐,是本人通過書籍、Java文檔、互連網資料總結並親自驗證的。

如果哪位道友發現有表達不準確的地方,歡迎指正,免得誤人誤己,多謝。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.