注解是一种特殊的接口
元注解
@Target 注解的作用目标。如字段、类、方法、注解等。
- ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
- ElementType.FIELD:允许作用在属性字段上
- ElementType.METHOD:允许作用在方法上
- ElementType.PARAMETER:允许作用在方法参数上
- ElementType.CONSTRUCTOR:允许作用在构造器上
- ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
- ElementType.ANNOTATION_TYPE:允许作用在注解上
- ElementType.PACKAGE:允许作用在包上
@Retention 指当前注解的生命周期
- RetentionPolicy.SOURCE:当前注解编译期可见,不会写入 class 文件
- RetentionPolicy.CLASS:类加载阶段丢弃,会写入 class 文件
- RetentionPolicy.RUNTIME:永久保存,可以反射获取
@Documented 执行javadoc打包时会被保存到doc文档中
@Inherited 是否具有继承性,注解的类的子类是否继承该该注解
1.在编译期间直接扫描的注解,如:
JDK三大注解
@override,会在编译时去查看是否真正的重写了父类方法;也就是在父类中是否存在同样的方法签名
@ Deprecated:标记当前方法、类等不再推荐使用。
@SuppressWarnings:压制java警告注解。value值为要压制的警告类型。
2.在运行期间反射。一般自定义注解是属于这类注解。
在运行期间,通过反射获取对象的元数据中存在注解信息。
注解在字节码中属性表:
- RuntimeVisibleAnnotations:运行时可见的注解
- RuntimeInVisibleAnnotations:运行时不可见的注解
- RuntimeVisibleParameterAnnotations:运行时可见的方法参数注解
- RuntimeInVisibleParameterAnnotations:运行时不可见的方法参数注解
- AnnotationDefault:注解类元素的默认值
反射中跟注解相关的方法:
- getAnnotation:返回指定的注解
- isAnnotationPresent:判定当前元素是否被指定注解修饰
- getAnnotations:返回所有的注解
- getDeclaredAnnotation:返回本元素的指定注解
- getDeclaredAnnotations:返回本元素的所有注解,不包含父类继承而来的
自定义注解通过JDK动态代理生成的代理类,通过Proxy.newProxyInstance调用执行的。
当生成代理类时,会传入被代理类的classLoader,代理的接口方法,和处理器。
InvocationHandler是接口实现处理器。他有很多实现,这里既然是代理注解,所以进入AnnotationInvocationHandler
下面这段代码是通过反射动态获取并修改属性的值。