#翻譯#使用註解處理器生成程式碼-1 註解型別

weixin_33806914發表於2016-02-21

 原文地址如下:摸我
 我希望以此篇博文作為基於註解處理器生成程式碼系列博文的開篇,給大家展示註解處理器有多麼強大,並在最後使用這項技術來在編譯時刻生成android程式碼
 在這個系列博文中,我們會:

  • 介紹Java語言中的註解
  • 理解註解的基本用法和作用域
  • 瞭解Annotation Processor基礎知識和作用
  • 學習如何在命令列,Eclipse,Maven中執行Annotation Processors
  • 學習如何使用Annotation Processors來生成程式碼
  • 學習如何Apache Velocity模版來生成程式碼

簡介

 註解首先在第三版Java Language Specification中被提出,並在java 5中被實現。
 使用註解我們可以給原始碼新增後設資料資訊,比如構造或者部署資訊,配置屬性,編譯特性或者程式碼質量檢查。
 不像Javadocs,註解是強型別的,每個註解都對應一個預先定義好的註解型別。除此之外,程式可以在執行時獲得註解資訊,Javadocs不行。

註解語法

 註解通常出現在被註解程式碼片段之前,單獨成行,並且和程式碼片段有相同的縮排。
 註解可以應用到包,型別(類,介面,列舉,註解型別),變數(物件,區域性變數-包括定義在迴圈結構中的變數),建構函式,方法,和引數。
 註解的最簡單形式是不帶任何元素,比如:

@Override()
    public void theMethod() {…}

 在這種情況下,括號可以被省略。

@Override
    public void theMethod() {…}

 註解可以包括通過冒號分離的鍵值對資料,型別可以是基礎型別,字串,列舉,和陣列:

@Author(name = "Albert",
            created = "17/09/2010",
            revision = 3,
            reviewers = {"George", "Fred"})
    public class SimpleAnnotationsTest {…}

 當註解只有一個元素並且其名字是value,那麼它就可以被省略:

@WorkProduct("WP00000182")
    @Complexity(ComplexityLevel.VERY_SIMPLE)
    public class SimpleAnnotationsTest {…}

 註解可以定義它的元素的預設值,有預設值的元素可以在註解宣告使用時被省略。
 比如,假設註解Author定義了revision(預設為1)和reviewers(預設為空的字串陣列),下邊的兩個註釋宣告是相同的:

@Author(name = "Albert",
            created = "17/09/2010",
            revision = 1,
            reviewers = {})
    public class SimpleAnnotationsTest() {…}
    @Author(name = "Albert",        // defaults are revision 1
            created = "17/09/2010") // and no reviewers
    public class SimpleAnnotationsTest() {…}

註解的典型使用

 有三類註解型別在Java Language Specification中被定義,它們提供給java的編譯器使用:

  • @Deprecated:表明被標記的元素不應該再被使用。當你使用被標記元素時,編譯器會給出警告。也可以使用在Javadoc中,解釋標記元素不能在使用的原因。
  • @Override:表面被標記元素為過載了超類中的元素
  • @SuppressWarnings:讓編譯器忽略標記元素會產生的一些特定警告

 自從註解被引入,很多庫和框架都在其最新版本中新增了註解。通過在程式碼中使用註解,這些庫或者框架可以減少或者去除配置檔案的使用。
 最有代表性的幾個庫或框架如下:

  • Java Enterprise Edition and its main components – Enterprise JavaBeans, Java Persistence API or Web Services API’s.
  • Spring Framework – used thoroughly for configuration, dependency injection and inversion of control in the core framework and in other Spring projects.
  • Seam, Weld, Guice.
  • Apache Struts 2.

註解型別

 註解型別(Annotation Type)是定義自定義註解的特殊介面(interface)。
 一個註解型別使用@interface來定義:

public @interface Author {
        String name();
        String created();
        int revision() default 1;
        String[] reviewers() default {};
    }
    public @interface Complexity {
        ComplexityLevel value() default ComplexityLevel.MEDIUM;
    }
    public enum ComplexityLevel {
        VERY_SIMPLE, SIMPLE, MEDIUM, COMPLEX, VERY_COMPLEX;
    }

 註解型別和常規的介面有一些不同的地方:

  • 只有基礎型別,字串,列舉,類常量和上述型別的陣列允許在註解定義中使用,一般的類和物件不允許使用,雙重陣列也不允許。
  • 註解元素的定義語法和類方法的語法相似,但是注意,註解元素的定義不包括修飾符和引數。
  • 預設值是使用default關鍵字定義的,其後的值必須是字面量,陣列初始器和列舉值。

 列舉型別可以在註解內部進行定義:

public @interface Complexity {
        public enum Level {
            VERY_SIMPLE, SIMPLE, MEDIUM, COMPLEX, VERY_COMPLEX;
        }
    …

用來定義註解的註解

 JDK中預先定義了一些用來修改自定義註解行為的註解:

  • @Retention:表明被標記的註解資訊會儲存多長時間,一些可能的值如下:CLASS (預設選項,註解資訊儲存到class檔案中,但是無法在執行時獲得), SOURCE (當class檔案被建立時被編譯器拋棄) and RUNTIME (在程式執行時可以獲得).
  • @Target:表明註解可以標記元素的型別,可能的值為列舉型別ElementType的值:ANNOTATION_TYPE, CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER and TYPE.
     下一篇博文為《註解處理器》,稍後會給出。


(1) ”The Java Language Specification, Third Edition” is available for free download here.
 Update: new link to relevant JLS section in his new home at Oracle site here.

相關文章