腳本API
在java中可以調(diào)用其他腳本語(yǔ)言寫(xiě)代碼楼入,比如JavaScript,Groovy牧抽,Ruby。一般需要引入兩個(gè)jar包集合扬舒,一個(gè)是腳本語(yǔ)言自身的jar包集合阐肤,一個(gè)是該腳本語(yǔ)言的腳本引擎jar包
編譯API
除了可以使用javac編譯工具進(jìn)行編譯源文件讲坎,還可以在程序運(yùn)行中調(diào)用編譯API進(jìn)行編譯代碼孕惜,而且代碼不僅可以是來(lái)自文件,也可以是來(lái)自其他地方晨炕,比如StringBuffer衫画。最簡(jiǎn)單的API是JavaCompiler的run方法,如果想要控制更多的編譯過(guò)程的細(xì)節(jié)瓮栗,可以使用CompilationTask類削罩,不過(guò)比較復(fù)雜,可以控制程序代碼的來(lái)源弥激,比如在StringBuffer;可以控制類文件的位置秆撮,比如存到數(shù)據(jù)庫(kù);可以監(jiān)聽(tīng)編譯過(guò)程中的錯(cuò)誤和警告信息换况,可以在后臺(tái)運(yùn)行編譯器。源碼的位置和類文件的位置是由JavaFileManager控制的戈二,位置用JavaFileObject類來(lái)表示舒裤,JavaFileObject可以表示磁盤(pán)的文件觉吭,也可以對(duì)應(yīng)其他位置
注解
注解本身并不會(huì)做任何事情腾供,它需要工具的支持(需要對(duì)應(yīng)的工具來(lái)處理)鲜滩,在一個(gè)地方打注解伴鳖,相當(dāng)于在這個(gè)地方打個(gè)標(biāo)記,注解對(duì)應(yīng)的工具來(lái)處理榜聂。所有的注解接口都隱式地?cái)U(kuò)展自java.lang.annotation.Annotation,而Annotation是一個(gè)常規(guī)接口嗓蘑,不是注解接口,注解接口無(wú)法被擴(kuò)展
- 定義注解
注解是由注解接口來(lái)定義的桩皿,一般定義的形式如下
modifiers @interface AnnotationName {
elementDeclaration1
elementDeclaration2
...
}
每個(gè)元素聲明都形如type elementName();
或者type elementName() default value;
豌汇,例如
@Target({ElementType.Method})
public @interface BugReport {
String assignedTo() default "none";
int level() = 0;
}
使用注解的時(shí)候如果不指定元素值泄隔,就會(huì)使用默認(rèn)值(也可能是該注解沒(méi)有聲明元素)拒贱,比如
@BugReport(assignedTo="Alice", level = 2)
public void f() {
...
}
- 元注解
@Target應(yīng)用于注解的定義上佛嬉,限制該注解可以運(yùn)用于哪些項(xiàng)上柜思,如果在定義一個(gè)注解的時(shí)候巷燥,沒(méi)有使用@Target赡盘,則該注解可以運(yùn)用于任何項(xiàng)。
類別 | 描述 |
---|---|
ElementType.ANNOTATION_TYOE | 注解類型聲明 |
ElementType.PACKAGE | 包 |
ElementType.TYPE | 類陨享,枚舉和接口 |
ElementType.METHOD | 方法 |
ElementType.CONSTRUCTOR | 構(gòu)造器 |
ElementType.FIELD | 字段 |
ElementType,PARAMETER | 方法或構(gòu)造器參數(shù) |
ElementType.LOCAL_VARIABLE | 局部變量 |
@Retention
用于指定注解應(yīng)該保存的時(shí)間(或階段)
類別 | 描述 |
---|---|
SOURCE | 只保留在源碼中 |
CLASS | 源碼和類文件中都保留葱淳,但虛擬機(jī)不將注解載入 |
RUNTIME | 源碼和類文件中都保留抛姑,虛擬機(jī)會(huì)載入注解 |
@Documented
表示是否歸檔
@Inherited
有@Inherited的注解只能用在類上赞厕,表示該注解能被子類繼承定硝,在類A上使用這種注解皿桑,那么A的子類自動(dòng)會(huì)繼承這個(gè)注解,比如@Serializable
如何獲取注解對(duì)象并進(jìn)行處理
思路:比如某個(gè)注解诲侮,名為BugReport,是用在方法上的箱蟆,那么我們獲得一個(gè)對(duì)象后,然后獲得對(duì)象的Class對(duì)象空猜,然后通過(guò)getDeclaredMethods()獲得Method集合绽慈,然后遍歷該Method集合,對(duì)每個(gè)Method對(duì)象調(diào)用BugReport br = m.getAnnotation(BugReport.class)
辈毯,如果在該方法上使用了注解坝疼,那么就會(huì)返回一個(gè)注解對(duì)象,否則返回null谆沃。然后我們就可以決定怎么處理了裙士。對(duì)于在其他項(xiàng)上的注解,同樣可以使用這個(gè)思路
注解的使用
注解可以在源碼階段管毙,字節(jié)碼階段腿椎,運(yùn)行階段做事情