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中并不存在.