注解的定义
注解是JDK1.5版本开始引入的一个特性,用于对代码进行说明,可以对包、类、接口、字段、方法参数、局部变量等进行注解。
它主要的作用有以下四方面:
①.生成文档,通过代码里标识的元数据生成javadoc文档。
②.编译检查,通过代码里标识的元数据让编译器在编译期间进行检查验证。
③.编译时动态处理,编译时通过代码里标识的元数据动态处理,例如动态生成代码。
④.运行时动态处理,运行时通过代码里标识的元数据动态处理,例如使用反射注入实例。
注解分类:
1.Java内置注解
java自带的标准注解:
@Override:标明重写某个方法@Deprecated:标明某个类或方法过时、标明要忽略的警告
@SuppressWarnings:
用这些注解标明后编译器就会进行检查。
2.元注解:注解在注解上的注解
@Target:描述注解的使用范围
Target注解用来说明那些被它所注解的注解类可修饰的对象范围,取值范围定义在ElementType 枚举中。
public enum ElementType {
TYPE, // 类、接口、枚举类
FIELD, // 成员变量(包括:枚举常量)
METHOD, // 成员方法
PARAMETER, // 方法参数
CONSTRUCTOR, // 构造方法
LOCAL_VARIABLE, // 局部变量
ANNOTATION_TYPE, // 注解类
PACKAGE, // 可用于修饰:包
TYPE_PARAMETER, // 类型参数,JDK 1.8 新增
TYPE_USE // 使用类型的任何地方,JDK 1.8 新增
}
@Retention:描述注解保留的时间范围,定义在RetentionPolicy枚举中。
public enum RetentionPolicy {
SOURCE, // 源文件保留
CLASS, // 编译期保留,默认值
RUNTIME // 运行期保留,可通过反射去获取注解信息
}
注意点:
SOURCE:
标记的注解仅在源码中,编译器忽略;
使用场景:APT(注解处理器),在使用javac时,先会找注解处理程序然后再转化成.class文件。
CLASS
字节码级别,会存在字节码中,但是编译的时候也会忽略它
使用场景:
字节码增强技术;热修复
RUNTIME
存在运行时
使用场景:与反射结合一起使用
示例伪代码:
cls = activity.getClass();//获取反射对象
Field[] filed = cls.getdeclaredFiled();
for(...){
if(filed.isAnnotationPresent(注解名.class))
{
A a = declaredFiled.getAnnotation(注解名.class);//获取注解
}
}
int id = a.value();
filed.setAccessible(true);//设置可以设置值的权限
@Documented:描述在使用javadoc 工具为类生成帮助文档时是否要保留其注解信息
@Inherited :被它修饰的annotation将具有继承性,如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解。
注解和反射
只有注解被定义为RUNTIME后,该注解才能是运行时可见,当class文件被装载时被保存在class文件中的Annotation才会被虚拟机读取。
各个api :
boolean isAnnotationPresent(Class<?extends Annotation> annotationClass)
判断该程序元素上是否包含指定类型的注解,存在则返回true,否则返回false。注意:此方法会忽略注解对应的注解容器。 、
T getAnnotation(Class annotationClass)
返回该程序元素上存在的、指定类型的注解,如果该类型注解不存在,则返回null。
Annotation[] getAnnotations()
返回该程序元素上存在的所有注解,若没有注解,返回长度为0的数组。
T[] getAnnotationsByType(Class annotationClass)
返回该程序元素上存在的、指定类型的注解数组。没有注解对应类型的注解时,返回长度为0的数组。该方法的调用者可以随意修改返回的数组,而不会对其他调用者返回的数组产生任何影响。getAnnotationsByType方法与 getAnnotation的区别在于,getAnnotationsByType会检测注解对应的重复注解容器。若程序元素为类,当前类上找不到注解,且该注解为可继承的,则会去父类上检测对应的注解。
T getDeclaredAnnotation(Class annotationClass)
返回直接存在于此元素上的所有注解。与此接口中的其他方法不同,该方法将忽略继承的注释。如果没有注释直接存在于此元素上,则返回null
T[] getDeclaredAnnotationsByType(Class annotationClass)
返回直接存在于此元素上的所有注解。与此接口中的其他方法不同,该方法将忽略继承的注释 Annotation[] getDeclaredAnnotations() 返回直接存在于此元素上的所有注解及注解对应的重复注解容器。与此接口中的其他方法不同,该方法将忽略继承的注解。如果没有注释直接存在于此元素上,则返回长度为零的一个数组。该方法的调用者可以随意修改返回的数组,而不会对其他调用者返回的数组产生任何影响。