您好,登錄后才能下訂單哦!
注解:
注解為我們在代碼中添加信息提供一種形式化的方法,使我們可以在源碼、編譯時、運行時非常方便的使用這些數據。
注解是在JAVA SE5中引入的,注解讓代碼更干凈易讀并且可以實現編譯期類型檢查等。當創建描述性質的類或接口時,如果有重復性的工作,就可以考慮使用注解來簡化或自動化該過程。我們可以讓注解保存在源代碼中,并且利用Annotation API處理注解,得到我們想要的數據并加以處理,注解的使用比較簡單,JAVA SE5內置了3種:
先來看內置注解@Override是怎么被定義的,它位于package java.lang之下:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
@Target、@Retention稱為元注解:元注解負責注解其他的注釋,如:@Target定義聲明的注解的作用域(作用在類上還是方法上)
br/>@Target定義聲明的注解的作用域(作用在類上還是方法上)
除了@Target、@Retention還有@Documented及@Inherited,下面用一個表格來分別列出他們各自的作用:
首先來自定義一個注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationInfo {
String[] value();
int requestCode() default 0;
}
@Target(ElementType.METHOD)指明了我們的注解是作用在方法上的
@Retention(RetentionPolicy.RUNTIME)表示注解在程序運行時期也會存在,即注解信息也會加載到虛擬機VM中,所以可以通過反射來獲取注解的相關信息:
public class AnnotationExample {
/**
* 注解模擬請求權限
*/
@AnnotationInfo(value = {"android.permission.CALL_PHONE", "android.permission.CAMERA"}, requestCode = 10)
public void requestPermission() {
//其他邏輯
}
}
接著來編寫一個運行時解析注解的Java類:AnnotationRuntimeProcessor.java
public class AnnotationRuntimeProcessor {
public static void main(String[] args) {
try {
//獲取AnnotationExample的Class對象
Class<?> cls = Class.forName("com.javastudy.Annotation.AnnotationExample");
//獲取AnnotationExample類中的方法
Method[] methods = cls.getDeclaredMethods();
for (Method method : methods) {
//過濾不含自定義注解AnnotationInfo的方法
boolean isHasAnnotation = method.isAnnotationPresent(AnnotationInfo.class);
if (isHasAnnotation) {
method.setAccessible(true);
//獲取方法上的注解
AnnotationInfo aInfo = method.getAnnotation(AnnotationInfo.class);
if (aInfo == null) return;
//解析注解上對應的信息
String[] permissions = aInfo.value();
System.out.println("value: " + Arrays.toString(permissions));
int requestCode = aInfo.requestCode();
System.out.println("requestCode: " + requestCode);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
上面的邏輯很簡單,反射拿到有注解對應類的Class對象,篩選含有注解的方法,最后獲取方法上的注解并解析,運行結果如下:
value: [android.permission.CALL_PHONE, android.permission.CAMERA]
requestCode: 10
AbstractProcessor是javax下的API,java和javax都是Java的API(Application Programming Interface)包,java是核心包,javax的x是extension的意思,也就是擴展包。一般繼承AbstractProcessor需要實現下面的幾個方法:
public class ProcessorExample extends AbstractProcessor {
@Override
public synchronized void init(ProcessingEnvironment processingEnvironment) {
//processingEnvironment提供各種工具類 如Elements Filer Types SourceVersion等
super.init(processingEnvironment);
}
/**
* 掃描 評估和處理注解代碼 生成Java代碼
*
* @param set 注解類型
* @param roundEnvironment 有關當前和以前的信息環境 查詢出包含特定注解的被注解元素
* @return 返回true 表示注解已聲明 后續Processor不會再處理 false表示后續Processor會處理他們
*/
@Override
public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnvironment) {
return false;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return super.getSupportedSourceVersion();
}
@Override
public Set<String> getSupportedAnnotationTypes() {
return super.getSupportedAnnotationTypes();
}
}
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。