1. Java SE5中内置了3中标准注解,以及4中元注解(用于注解其他的注解),注解一旦构造出来就享有编译期的类型检查保护。
注解元素可用的类型
String
Class
enum
Annotation
以上类型的数组
3种标准注解:@Override,@Deprecated,@SuppressWarnings
4种元注解:
注解分类按生命周期由短到长可分为:
RetentionPolicy.SOURCE:源码注解,注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃(在编译器处理期间源码注解还存在,即注解处理器Processor也能处理源码注解,编译器处理完之后就没有该注解信息了);
RetentionPolicy.CLASS:编译时注解,注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期;
RetentionPolicy.RUNTIME:运行时注解,注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在;
这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码。
首先要明确生命周期长度SOURCE < CLASS < RUNTIME,所以前者能作用的地方后者一定也能作用。一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如ButterKnife),就用 CLASS注解;如果只是做一些检查性的操作,比如@Override和@SuppressWarnings,则可选用 SOURCE 注解。
获取注解的方式:
需要通过反射来获取运行时注解,要使用这些函数必须先通过反射获取到对应的元素:Class、Field、Method,再通过getDeclaredAnnotations()拿到注解。
编译时注解需要用注解处理器(Annotation Processor)来获取,因为这里是真正体现编译时注解价值的地方。需要注意的一点是,运行时注解(RetentionPolicy.RUNTIME)和源码注解(RetentionPolicy.SOURCE)也可以在注解处理器进行处理
2.在Android Support Library19.1版本中,Android工具小组引入了几个注解类型
有三种类型的注解可供我们使用:
@Retention(SOURCE)都是源码注解
Nullness注解;
资源类型注解;
IntDef和StringDef注解;
3.注解处理器
主要用于处理编译时注解,注解处理器只在编译处理期间需要用到,编译处理完后就没有实际作用了。
注解处理器是javac的一个工具,它用来在编译时扫描和处理注解(Annotation)。你可以自定义注解,并注册到相应的注解处理器,由注解处理器来处理你的注解。注解处理器,以Java代码(或者编译过的字节码)作为输入,生成文件(通常是.java文件)作为输出。
每一个处理器都是继承于AbstractProcessor,并要求必须复写process()方法,通常我们使用会去复写以下4个方法:
init(ProcessingEnvironment env): 每一个注解处理器类都必须有一个空的构造函数。然而,这里有一个特殊的init()方法,它会被注解处理工具调用,并输入ProcessingEnviroment参数。ProcessingEnviroment提供很多有用的工具类Elements, Types和Filer。后面我们将看到详细的内容。
process(Set annotations, RoundEnvironment env): 这相当于每个处理器的主函数main()。你在这里写你的扫描、评估和处理注解的代码,以及生成Java文件。输入参数RoundEnviroment,可以让你查询出包含特定注解的被注解元素。后面我们将看到详细的内容。
getSupportedAnnotationTypes(): 这里你必须指定,这个注解处理器是注册给哪个注解的。注意,它的返回值是一个字符串的集合,包含本处理器想要处理的注解类型的合法全称。换句话说,你在这里定义你的注解处理器注册到哪些注解上。
getSupportedSourceVersion(): 用来指定你使用的Java版本。通常这里返回SourceVersion.latestSupported()。然而,如果你有足够的理由只支持Java 6的话,你也可以返回SourceVersion.RELEASE_6。我推荐你使用前者。
网友评论