自定义注解
元注解-@Retention元注解
根据反射的测试的问题,引出@Retention元注解的讲解:其三种取值:
RetentionPolicy.SOURCE
RetentionPolicy.CLASS
RetentionPolicy.RUNTIME
分别对应:Java源文件(.java文件)---->.class文件---->内存中的字节码
@Retention(RetentionPolicy.SOURCE)
这个注解的意思是让MyAnnotation注解只在java源文件中存在,编译成.class文件后注解就不存在了
@Retention(RetentionPolicy.CLASS)
这个注解的意思是让MyAnnotation注解在java源文件(.java文件)中存在,编译成.class文件后注解也还存在,
@ Retention(RetentionPolicy.RUNTIME)
注解的生命周期一直程序运行时都存在
元注解-@Target元注解
@Target元注解决定了一个注解可以标识到哪些成分上,如标识在在类身上,或者属性身上,或者方法身上等成分,@Target默认值为任何元素(成分)
ElementType 是一个枚举类型,有以下一些值:
ElementType.TYPE:允许被修饰的注解作用在类、接口和枚举上 *** *
ElementType.FIELD:允许作用在属性字段上 * ElementType.METHOD:允许作用在方法上 *
ElementType.PARAMETER:允许作用在方法参数上 *
ElementType.CONSTRUCTOR:允许作用在构造器上 *
ElementType.LOCAL_VARIABLE:允许作用在本地局部变量上 *
ElementType.ANNOTATION_TYPE:允许作用在注解上 *
ElementType.PACKAGE:允许作用在包上
示例:
@Target( { ElementType.METHOD, ElementType.TYPE })
-
元注解-@Documented:注解是否应当被包含在 JavaDoc 文档中
-
元注解-@Inherited:是否允许子类继承该注解
@Inherited注解,是指定某个自定义注解如果写在了父类的声明部分,那么子类的声明部分也能自动拥有该注解。@Inherited注解只对那些@Target被定义为ElementType.TYPE的自定义注解起作用。
注解介绍
一个注解准确意义上来说,只不过是一种特殊的注释而已,如果没有解析它的代码,它可能连注释都不如。
而解析一个类或者方法的注解往往有两种形式,一种是编译期直接的扫描,一种是运行期反射。反射的事情我们待会说,而编译器的扫描指的是编译器在对 java 代码编译字节码的过程中会检测到某个类或者方法被一些注解修饰,这时它就会对于这些注解进行某些处理。
典型的就是注解 @Override,一旦编译器检测到某个方法被修饰了 @Override 注解,编译器就会检查当前方法的方法签名是否真正重写了父类的某个方法,也就是比较父类中是否具有一个同样的方法签名。
这一种情况只适用于那些编译器已经熟知的注解类,比如 JDK 内置的几个注解,而你自定义的注解,编译器是不知道你这个注解的作用的,当然也不知道该如何处理,往往只是会根据该注解的作用范围来选择是否编译进字节码文件,仅此而已。
注解的使用
「注解的本质就是一个继承了 Annotation 接口的接口」
对于一个类或者接口来说,Class 类中提供了以下一些方法用于反射注解。
getAnnotation:返回指定的注解
isAnnotationPresent:判定当前元素是否被指定注解修饰
getAnnotations:返回所有的注解
getDeclaredAnnotation:返回本元素的指定注解
getDeclaredAnnotations:返回本元素的所有注解,不包含父类继承而来的
注解本质上是继承了 Annotation 接口的接口,而当你通过反射,也就是我们这里的 getAnnotation 方法去获取一个注解类实例的时候,其实 JDK 是通过动态代理机制生成一个实现我们注解(接口)的代理类。