轉:Java Annotation詳解

來源:互聯網
上載者:User

轉載自:http://william750214.javaeye.com/blog/298104

中繼資料的作用

如果要對於中繼資料的作用進行分類,目前還沒有明確的定義,不過我們可以根據它所起的作用,大致可分為三類:

l         編寫文檔:通過代碼裡標識的中繼資料產生文檔。

l         程式碼分析:通過代碼裡標識的中繼資料對代碼進行分析。

l         編譯檢查:通過代碼裡標識的中繼資料讓編譯器能實現基本的編譯檢查。

 

基本內建注釋

    @Override注釋能實現編譯時間檢查,你可以為你的方法添加該注釋,以聲明該方法是用於覆蓋父類中的方法。如果該方法不是覆蓋父類的方法,將會在編譯時間報錯。例如我們為某類重寫toString()方法卻寫成了tostring(),並且我們為該方法添加了@Override注釋;

     @Deprecated的作用是對不應該在使用的方法添加註釋,當編程人員使用這些方法時,將會在編譯時間顯示提示資訊,它與javadoc裡的@deprecated標記有相同的功能,準確的說,它還不如javadoc @deprecated,因為它不支援參數,

注意:要瞭解詳細資料,請使用 -Xlint:deprecation 重新編譯。

    @SuppressWarnings與前兩個注釋有所不同,你需要添加一個參數才能正確使用,這些參數值都是已經定義好了的,我們選擇性的使用就好了,參數如下:

 

deprecation   使用了過時的類或方法時的警告

unchecked  執行了未檢查的轉換時的警告,例如當使用集合時沒有用泛型 (Generics) 來指定集合儲存的類型

fallthrough   當 Switch 程式塊直接通往下一種情況而沒有 Break 時的警告

path   在類路徑、源檔案路徑等中有不存在的路徑時的警告

serial 當在可序列化的類上缺少 serialVersionUID 定義時的警告

finally    任何 finally 子句不能正常完成時的警告

all 關於以上所有情況的警告

 

注意:要瞭解詳細資料,請使用 -Xlint:unchecked 重新編譯。

 

定製注釋類型

    好的,讓我們建立一個自己的注釋類型(annotation type)吧。它類似於新建立一個介面類檔案,但為了區分,我們需要將它聲明為@interface,如下例:

public @interface NewAnnotation {

 

}

 

使用定製的注釋類型

    我們已經成功地建立好一個注釋類型NewAnnotation,現在讓我們來嘗試使用它吧,如果你還記得本文的第一部分,那你應該知道他是一個標記注釋,使用也很容易,如下例:

public class AnnotationTest {

 

    @NewAnnotation

    public static void main(String[] args) {

 

    }

}

 

添加變數

    J2SE 5.0裡,我們瞭解到內建注釋@SuppressWarnings()是可以使用參數的,那麼自訂注釋能不能定義參數個數和類型呢?答案是當然可以,但參數類型只允許為基本類型、String、Class、枚舉類型等,並且參數不可為空。我們來擴充NewAnnotation,為之添加一個String類型的參數,範例程式碼如下:

public @interface NewAnnotation {

 

    String value();

}

    使用該注釋的代碼如下:正如你所看到的,該注釋的使用有兩種寫法,這也是在之前的文章裡所提到過的。如果你忘了這是怎麼回事,那就再去翻翻吧。

public class AnnotationTest {

 

    @NewAnnotation("Just a Test.")

    public static void main(String[] args) {

        sayHello();

    }

 

    @NewAnnotation(value="Hello NUMEN.")

    public static void sayHello() {

        // do something

    }

}

 

為變數賦預設值

    我們對Java自訂注釋的瞭解正在不斷的增多,不過我們還需要更過,在該條目裡我們將瞭解到如何為變數設定預設值,我們再對NewAnnotaion進行修改,看看它會變成什麼樣子,不僅參數多了幾個,連類名也變了。但還是很容易理解的,我們先定義一個枚舉類型,然後將參數設定為該枚舉類型,並賦予預設值。

public @interface Greeting {

 

    public enum FontColor {RED, GREEN, BLUE};

 

    String name();

 

    String content();

 

    FontColor fontColor() default FontColor.BLUE;

}

 

限定注釋使用範圍

    當我們的自訂注釋不斷的增多也比較複雜時,就會導致有些開發人員使用錯誤,主要表現在不該使用該注釋的地方使用。為此,Java提供了一個ElementType枚舉類型來控制每個注釋的使用範圍,比如說某些注釋只能用於普通方法,而不能用於建構函式等。下面是Java定義的ElementType枚舉:

package java.lang.annotation;

 

public enum ElementType {

  TYPE,         // Class, interface, or enum (but not annotation)

  FIELD,        // Field (including enumerated values)

  METHOD,       // Method (does not include constructors)

  PARAMETER,        // Method parameter

  CONSTRUCTOR,      // Constructor

  LOCAL_VARIABLE,   // Local variable or catch clause

  ANNOTATION_TYPE,  // Annotation Types (meta-annotations)

  PACKAGE       // Java package

}

    下面我們來修改Greeting注釋,為之添加限定範圍的語句,這裡我們稱它為目標(Target)使用方法也很簡單,如下:

 

@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })

public @interface Greeting {

}

正如上面代碼所展示的,我們只允許Greeting注釋標註在普通方法和建構函式上,使用在包申明、類名等時,會提示錯誤資訊。

 

注釋保持性策略

public enum RetentionPolicy {

  SOURCE,// Annotation is discarded by the compiler

  CLASS,// Annotation is stored in the class file, but ignored by the VM

  RUNTIME// Annotation is stored in the class file and read by the VM

}

    RetentionPolicy的使用方法與ElementType類似,簡單程式碼範例如下:

@Retention(RetentionPolicy.RUNTIME)

@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })

 

文檔化功能

    Java提供的Documented元注釋跟Javadoc的作用是差不多的,其實它存在的好處是開發人員可以定製Javadoc不支援的文件屬性,並在開發中應用。它的使用跟前兩個也是一樣的,簡單程式碼範例如下:

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })

public @interface Greeting {

}

 

值得大家注意的是,如果你要使用@Documented元注釋,你就得為該注釋設定RetentionPolicy.RUNTIME保持性策略。為什麼這樣做,應該比較容易理解,這裡就不提了。

 標註繼承

 

繼承應該是Java提供的最複雜的一個元注釋了,它的作用是控制注釋是否會影響到子類,簡單程式碼範例如下:

@Inherited

@Documented

@Retention(RetentionPolicy.RUNTIME)

@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })

public @interface Greeting {

}

 

讀取注釋資訊

    當我們想讀取某個注釋資訊時,我們是在運行時通過反射來實現的,如果你對元注釋還有點印象,那你應該記得我們需要將保持性原則設定為RUNTIME,也就是說只有注釋標記了@Retention(RetentionPolicy.RUNTIME)的,我們才能通過反射來獲得相關資訊,下面的例子我們將沿用前面幾篇文章中出現的代碼,並實現讀取AnnotationTest類所有方法標記的注釋並列印到控制台。好了,我們來看看是如何?的吧:

public class AnnotationIntro {

 

    public static void main(String[] args) throws Exception {

 

        Method[] methods = Class.forName(

                "com.gelc.annotation.demo.customize.AnnotationTest")

                .getDeclaredMethods();

        Annotation[] annotations;

 

        for (Method method : methods) {

            annotations = method.getAnnotations();

            for (Annotation annotation : annotations) {

                System.out.println(method.getName() + " : "

                        + annotation.annotationType().getName());

            }

 

 

 

Java並發編程中,用到了一些專門為並發編程準備的 Annotation。
主要包括三類:
1、類 Annotation(註解)
就像名字一樣,這些註解是針對類的。主有要以下三個:
@Immutable
@ThreadSafe
@NotThreadSafe

@ThreadSafe 是表示這個類是安全執行緒的。具體是否真安全,那要看實現者怎麼實現的了,反正打上這個標籤只是表示一下。不安全執行緒的類打上這個註解也沒事兒。
@Immutable 表示,類是不可變的,包含了 @ThreadSafe 的意思。
      @NotThreadSafe 表示這個類不是安全執行緒的。如果是安全執行緒的非要打上這個註解,那也不會報錯。

這三個註解,對使用者和維護者是有益的,使用者可以立即看出來這個類是否是安全執行緒的,維護者則是可以根據這個註解,重點檢查安全執行緒方面。另外,程式碼分析工具可能會利用這個註解。

2、域 Annotation(註解)
域註解是對類裡面成員變數加的註解。
3、方法 Annotation(註解)
方法註解是對類裡面方法加的註解。

域註解和方法註解都是用@GuardedBy( lock )來標識。裡面的Lock是告訴維護者:這個狀態變數,這個方法被哪個鎖保護著。這樣可以強烈的提示類的維護者注意這裡。

@GuardedBy( lock )有以下幾種使用形式:

1、@GuardedBy( "this" ) 受對象內部鎖保護
2、@GuardedBy( "fieldName" ) 受 與fieldName引用相關聯的鎖 保護。
3、@GuardedBy( "ClassName.fieldName" ) 受 一個類的靜態field的鎖 儲存。
4、@GuardedBy( "methodName()" ) 鎖對象是 methodName() 方法的返值,受這個鎖保護。
5、@GuardedBy( "ClassName.class" ) 受 ClassName類的直接鎖對象保護。而不是這個類的某個執行個體的鎖對象。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.