注解(Annotation)
注解概述
SE中常见的**@Override,@Deprecated**都是注解
如何去自定义Annotation
自定义的注解,必须配合上反射才有意义(所以说注解也叫标记确实没错)(使用反射获取注解,获取到注解之后,再根据注解中的内容,去做相应操作)
元注解
@Retention
修饰Annotation的生命周期
所以自定义的注解需要@Retention(Policy.RUNTIME) 保留到虚拟机运行中,使得反射能够获取到
@Target
这个也是用来修饰Annotation的,指定了这个,就是指定了,该注解能写到哪些程序元素上。
剩下两个
一个基本不用的@Documented
还有一个使用较少的@Inherited
jdk8中注解新特性
可重复注解@Repeatable
上代码,这样,就可以在类上面写重复的多个注解了(如果不实现MyAnnotations,是不可以写多个的),但是多个其实也没太多必要,你直接把需要多个的属性,定义成一个数组不就得了?
import java.lang.annotation.*;
@Repeatable(MyAnnotations.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation{
String[] value() default "hello";
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@interface MyAnnotations{
MyAnnotation[] value();
}
@MyAnnotation(value = "456")
@MyAnnotation(value = "123")
class Person{
}
类型注解
在Target属性中多出的两个注解,可修饰泛型
注解的原理
注解本质上是继承了 Annotation 接口的接口,而当你通过反射,也就是我们这里的 getAnnotation 方法去获取一个注解类实例的时候,其实 JDK 是通过动态代理机制生成一个实现我们注解(接口)的代理类。
参见博文https://www.cnblogs.com/yangming1996/p/9295168.html
而在动态代理中这个关键的 InvocationHandler 实例是谁?
AnnotationInvocationHandler 是 JAVA 中专门用于处理注解的 Handler, 这个类的设计也非常有意思。
自定义注解的应用
那就是反射,如果是空注解,那可能是标记,反射一旦获取到这个注解,就做一些对应的事情;
如果是非空注解,那么拿到注解的值之后,再去做一些对应的事情。