重学Java—注解和反射详解

注解的定义

注解是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() 返回直接存在于此元素上的所有注解及注解对应的重复注解容器。与此接口中的其他方法不同,该方法将忽略继承的注解。如果没有注释直接存在于此元素上,则返回长度为零的一个数组。该方法的调用者可以随意修改返回的数组,而不会对其他调用者返回的数组产生任何影响。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值