自定义注解及反射
什么是注解?
注解是一种能被添加到java源代码中的元数据,方法、类、参数和包都可以用注解来修饰。注解可以看作是一种特殊的标记,可以用在方法、类、参数和包上,程序在编译或者运行时可以检测到这些标记而进行一些特殊的处理。
4种元注解:
@Target,
@Retention,
@Documented,
@Inherited
元注解的作用就是负责注解其他注解。
@Target:
表示可以应用在哪里
同时可以通过value值进行限制
@Target(value = {ElementType.FIELD})
-
ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上
-
ElementType.FIELD:允许作用在属性字段上
-
ElementType.METHOD:允许作用在方法上
-
ElementType.PARAMETER:允许作用在方法参数上
-
ElementType.CONSTRUCTOR:允许作用在构造器上
-
ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上
-
ElementType.ANNOTATION_TYPE:允许作用在注解上
-
ElementType.PACKAGE:允许作用在包上
@Retention
定义被它所注解的注解保留多久,一共有三种策略,定义在RetentionPolicy枚举中.
从注释上看:
source:注解只保留在源文件,当Java文件编译成class文件的时候,注解被遗弃;被编译器忽略
class:注解被保留到class文件,但jvm加载class文件时候被遗弃,这是默认的生命周期
runtime:注解不仅被保存到class文件中,jvm加载class文件之后,仍然存在
这3个生命周期分别对应于:Java源文件(.java文件) ---> .class文件 ---> 内存中的字节码。
那怎么来选择合适的注解生命周期呢?
首先要明确生命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要在编译时进行一些预处理操作,比如生成一些辅助代码,就用 CLASS注解;如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,则可选用 SOURCE 注解。
@Document
表明该注解标记的元素可以被Javadoc 或类似的工具文档化。
@Inherited
表明使用了@Inherited注解的注解,所标记的类的子类也会拥有这个注解。
OK,知道这些,让我们来自定义一个注解
接下来,我们写一个类:
我们可以通过反射,拿到这个类,并且判断其方法是否有注解标记