?原文地址如下:摸我
?我希望以此篇博文作為基于注解處理器生成代碼系列博文的開篇硬鞍,給大家展示注解處理器有多么強(qiáng)大镜悉,并在最后使用這項技術(shù)來在編譯時刻生成android代碼
?在這個系列博文中灵迫,我們會:
- 介紹Java語言中的注解
- 理解注解的基本用法和作用域
- 了解
Annotation Processor
基礎(chǔ)知識和作用 - 學(xué)習(xí)如何在命令行,
Eclipse
,Maven
中運(yùn)行Annotation Processors
- 學(xué)習(xí)如何使用
Annotation Processors
來生成代碼 - 學(xué)習(xí)如何
Apache Velocity
模版來生成代碼
簡介
?注解首先在第三版Java Language Specification
中被提出,并在java 5
中被實(shí)現(xiàn)。
?使用注解我們可以給源代碼添加元數(shù)據(jù)信息被丧,比如構(gòu)造或者部署信息盟戏,配置屬性,編譯特性或者代碼質(zhì)量檢查甥桂。
?不像Javadocs
柿究,注解是強(qiáng)類型的,每個注解都對應(yīng)一個預(yù)先定義好的注解類型黄选。除此之外蝇摸,程序可以在運(yùn)行時獲得注解信息,Javadocs
不行办陷。
注解語法
?注解通常出現(xiàn)在被注解代碼片段之前貌夕,單獨(dú)成行,并且和代碼片段有相同的縮進(jìn)懂诗。
?注解可以應(yīng)用到包蜂嗽,類型(類,接口殃恒,枚舉,注解類型)辱揭,變量(對象离唐,局部變量-包括定義在循環(huán)結(jié)構(gòu)中的變量),構(gòu)造函數(shù)问窃,方法亥鬓,和參數(shù)。
?注解的最簡單形式是不帶任何元素域庇,比如:
@Override()
public void theMethod() {…}
?在這種情況下嵌戈,括號可以被省略。
@Override
public void theMethod() {…}
?注解可以包括通過冒號分離的鍵值對數(shù)據(jù)听皿,類型可以是基礎(chǔ)類型熟呛,字符串,枚舉尉姨,和數(shù)組:
@Author(name = "Albert",
created = "17/09/2010",
revision = 3,
reviewers = {"George", "Fred"})
public class SimpleAnnotationsTest {…}
?當(dāng)注解只有一個元素并且其名字是value庵朝,那么它就可以被省略:
@WorkProduct("WP00000182")
@Complexity(ComplexityLevel.VERY_SIMPLE)
public class SimpleAnnotationsTest {…}
?注解可以定義它的元素的默認(rèn)值,有默認(rèn)值的元素可以在注解聲明使用時被省略又厉。
?比如九府,假設(shè)注解Author
定義了revision
(默認(rèn)為1)和reviewers
(默認(rèn)為空的字符串?dāng)?shù)組),下邊的兩個注釋聲明是相同的:
@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:表明被標(biāo)記的元素不應(yīng)該再被使用侄旬。當(dāng)你使用被標(biāo)記元素時,編譯器會給出警告煌妈。也可以使用在
Javadoc
中儡羔,解釋標(biāo)記元素不能在使用的原因宣羊。 - @Override:表面被標(biāo)記元素為重載了超類中的元素
- @SuppressWarnings:讓編譯器忽略標(biāo)記元素會產(chǎn)生的一些特定警告
?自從注解被引入,很多庫和框架都在其最新版本中添加了注解笔链。通過在代碼中使用注解段只,這些庫或者框架可以減少或者去除配置文件的使用。
&emsp鉴扫;最有代表性的幾個庫或框架如下:
- 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;
}
?注解類型和常規(guī)的接口有一些不同的地方:
- 只有基礎(chǔ)類型,字符串坪创,枚舉炕婶,類常量和上述類型的數(shù)組允許在注解定義中使用,一般的類和對象不允許使用莱预,雙重數(shù)組也不允許柠掂。
- 注解元素的定義語法和類方法的語法相似,但是注意依沮,注解元素的定義不包括修飾符和參數(shù)涯贞。
- 默認(rèn)值是使用
default
關(guān)鍵字定義的,其后的值必須是字面量危喉,數(shù)組初始器和枚舉值宋渔。
?枚舉類型可以在注解內(nèi)部進(jìn)行定義:
public @interface Complexity {
public enum Level {
VERY_SIMPLE, SIMPLE, MEDIUM, COMPLEX, VERY_COMPLEX;
}
…
用來定義注解的注解
?JDK中預(yù)先定義了一些用來修改自定義注解行為的注解:
-
@Retention:表明被標(biāo)記的注解信息會保存多長時間,一些可能的值如下:
CLASS
(默認(rèn)選項辜限,注解信息保存到class文件中皇拣,但是無法在運(yùn)行時獲得),SOURCE
(當(dāng)class文件被創(chuàng)建時被編譯器拋棄) andRUNTIME
(在程序運(yùn)行時可以獲得). -
@Target:表明注解可以標(biāo)記元素的類型,可能的值為枚舉類型
ElementType
的值:ANNOTATION_TYPE
,CONSTRUCTOR
,FIELD
,LOCAL_VARIABLE
,METHOD
,PACKAGE
,PARAMETER
andTYPE
.
?下一篇博文為《注解處理器》薄嫡,稍后會給出氧急。
—
(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.