An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and packages may be annotated. Annotations have no direct effect on the operation of the code they annotate.java
建立自定義Annotation流程android
public @interface CustomAnnotation{***}
複製代碼
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.TYPE )
public @interface CustomAnnotation{***}
複製代碼
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.TYPE )
public @interface CustomAnnotation{
//註解參數類型能夠是1-6中任一種,包括枚舉
public enum Skill{JAVA,ANDROID,IOS}
Skill mySkill() default Skill.ANDROID;
String attr1();
//可使用default設置默認值
int attr2() default 100;
//修飾符只能用public
public boolean attr3() default false;
}
@Retention( RetentionPolicy.RUNTIME )
@Target( ElementType.TYPE )
public @interface CustomAnnotation{
//只有一個註解參數,使用value()
String value();
}
複製代碼
自定義Annotation的註解參數的默認值數組
註解元素必須有肯定的值,要麼在定義註解的默認值中指定,要麼在使用註解時指定,非基本類型的註解元素的值不可爲null。所以, 使用空字符串或0做爲默認值是一種經常使用的作法。這個約束使得處理器很難表現一個元素的存在或缺失的狀態,由於每一個註解的聲明中,全部元素都存在,而且都具備相應的值,爲了繞開這個約束,咱們只能定義一些特殊的值,例如空字符串或者負數,一次表示某個元素不存在,在定義註解時,這已經成爲一個習慣用法。bash
示例:
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnotherAnnotation{
String author() default "";
int age() default -1;
}
複製代碼
使用剛剛建立的自定義註解app
@CustomAnnotation(attr1 = "屬性1", attr2 = 90, attr3 = true)
public class AnnotationTestClass{
***
}
複製代碼
運行時 Annotation 解析框架
運行時 Annotation 指 @Retention 爲 RUNTIME 的 Annotationide
public void testCustomAnnotation() {
try {
Class cls = Class.forName("com.jet.annotation.AnnotationTestClass");
CustomAnnotation customAnnotation = (CustomAnnotation)cls.getAnnotation(CustomAnnotation.class);
System.out.println("customAnnotation mySkill:" + cus.mySkill());
System.out.println("customAnnotation attr1:" + cus.attr1());
System.out.println("customAnnotation attr2:" + cus.attr2());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
複製代碼
編譯時 Annotation 解析工具
編譯時 Annotation 指 @Retention 爲 CLASS 的 Annotation,甴編譯器自動解析性能
編譯時Annotation解析 相對複雜,下面單獨進行分析ui
首先申明:下面內容僅僅討論 編譯時Annotation的解析
public abstract class AbstractProcessor implements Processor {
//對一些工具進行初始化
public synchronized void init(ProcessingEnvironment processingEnv)
//你在這裏定義你的註解處理器註冊到哪些註解上,必須指定;
//它的返回值是一個字符串的集合,包含本處理器想要處理的註解類型的合法全稱
public Set<String> getSupportedAnnotationTypes()
//指定該註解處理器使用的JAVA版本,一般返回SourceVersion.latestSupported()
public SourceVersion getSupportedSourceVersion()
//真正生成java代碼的地方
//annotations:請求處理的註解類型集合
//roundEnv:可讓你查詢出包含特定註解的被註解元素,至關於「有關全局源碼的上下文環境」
//若是返回 true,則這些註解已聲明而且不要求後續 Processor 處理它們;
//若是返回 false,則這些註解未聲明而且可能要求後續 Processor 處理它們
public abstract boolean process(Set<? extends TypeElement> annotations,RoundEnvironment roundEnv)
}
複製代碼
關於編譯時Annotation解析,這裏推薦一篇文章【Android】註解框架(三)-- 編譯時註解,手寫ButterKnife,按照文章上面流程敲一遍代碼,相信能夠對自定義註解的建立及解析有一個深刻的瞭解!
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
//API模塊:android library
implementation project(':butterknife')
//Annotation模塊:java library
implementation project(':butterknife-annotations')
//Annotation解析模塊:java library
annotationProcessor project(':butterknife-compiler')
}
複製代碼
實際在打包生成APK的過程當中,只有 API模塊和Annotation模塊 會被打包進APK,Annotation解析模塊是提供給IDE使用的,在咱們APK中並不存在.