源碼注解(RetentionPolicy.SOURCE)的生命周期只存在Java源文件這一階段,是3種生命周期中最短的注解。當(dāng)在Java源程序上加了一個注解,這個Java源程序要由javac去編譯,javac把java源文件編譯成.class文件,在編譯成class時會把Java源程序上的源碼注解給去掉。需要注意的是,在編譯器處理期間源碼注解還存在,即注解處理器Processor 也能處理源碼注解,編譯器處理完之后就沒有該注解信息了。
(關(guān)于注解處理器Processor的詳細(xì)用法放在編譯時注解RetentionPolicy.CLASS里說明,或則可以先看這個:Java注解處理器使用詳解)
在這里就不用注解處理器來處理源碼注解了,來看一個我之前看到的挺有用的用法。
自定義注解
在開始寫注解前,先來考慮我們平時會遇到的一種情況:
我們定義的類有一個 int 型的狀態(tài)參數(shù)要設(shè)置,但我們設(shè)置的狀態(tài)又只能限定在[OPEN=1, CLOSE=2]這兩種狀態(tài),如果我們要提供一個接口來設(shè)置的話,那么一種做法是定義一個Enum枚舉來作為參數(shù),這樣就能限定參數(shù)的取值范圍了,但是使用枚舉會比常量占用更多的內(nèi)存。
這里可以用注解來處理這種問題,也就是下面要講的自定義源碼注解,這里需要用到一個元注解@IntDef(限定整型數(shù)據(jù)范圍),來看下代碼:
/**
* 測試源碼注解
*/
public class TestSourceAnnotation {
// 狀態(tài)值
public static final int STATUS_OPEN = 1;
public static final int STATUS_CLOSE = 2;
private static int sStatus = STATUS_OPEN;
private TestSourceAnnotation() {}
// 定義適用于參數(shù)的注解,限定取值范圍為{STATUS_OPEN, STATUS_CLOSE}
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.PARAMETER)
@IntDef({STATUS_OPEN, STATUS_CLOSE})
public @interface Status {
}
/**
* 定義方法并使用@Status限定參數(shù)的取值
* @param status
*/
public static void setStatus(@Status int status) {
sStatus = status;
}
public static int getStatus() {
return sStatus;
}
public static String getStatusDesc() {
if (sStatus == STATUS_OPEN) {
return "打開狀態(tài)";
} else {
return "關(guān)閉狀態(tài)";
}
}
}
這里定義了一個@Status注解,并用注解@IntDef限定了取值范圍,最后將@****Status注解用在參數(shù)上就行了,這樣在使用調(diào)用方法的使用只能使用指定的參數(shù){STATUS_OPEN, STATUS_CLOSE},就算用數(shù)值1編譯器也會提示報錯。除了@IntDef注解外還用一個@StringDef注解可以使用,用來處理字符串。
看下使用代碼:
/**
* 測試源碼注解
*/
private void _testSourceAnnotation() {
if (mIsOpen) {
//TestSourceAnnotation.setStatus(1); 直接設(shè)置數(shù)值編譯器會直接提示錯誤
TestSourceAnnotation.setStatus(TestSourceAnnotation.STATUS_CLOSE);
mIsOpen = false;
} else {
TestSourceAnnotation.setStatus(TestSourceAnnotation.STATUS_OPEN);
mIsOpen = true;
}
mTvDesc.setText(TestSourceAnnotation.getStatusDesc());
}