一、注解
注解:可以看作是对 一个 类/方法 的一个扩展的模版,每个 类/方法 按照注解类中的规则,来为 类/方法 注解不同的参数,在用到的地方可以得到不同的 类/方法 中注解的各种参数与值。
1、注解与XML区别
注解:是一种分散式的元数据,与源代码紧绑定
XML:是一种集中式的元数据,与源代码无绑定
2、注解的用途
- 生成文档:通过代码里标识的元数据生成javadoc文档
- 编译检查:通过代码里标识的元数据让编译器在编译期间进行检查验证
- 编译时动态处理:编译时通过代码里标识的元数据动态处理,例如动态生成代码
- 运行时动态处理:运行时通过代码里标识的元数据动态处理,例如使用反射注入实例
3、注解的三种分类
- Java自带的标准注解
- 元注解(元注解是用于定义注解的注解)
- 自定义注解
二、什么是元注解?
元注解是可以注解上注解上的注解,也可以说元注解是一种基本注解,但是元注解可以应用到其他注解上。而元注解的作用和目的是为了给普通的标签进行解释说明的。
1、元注解有几种?
1、@Retention存活时间
@Retention去给一张标签解释时,它指定了这张标签张贴的时间,相当于给一张标签上面盖了一张时间戳,时间戳指明了标签张贴的时间周期
取值如下:
- RetentionPolicy.SOURCE:注解只在源码阶段保留,在编译器进行编译时它将被丢弃忽视
- RetentionPolicy.CLASS:注解只被保留到编译进行的时候,它并不会被加载到JVM中
- RetentionPolicy.RUNTIME:注解可以保留到程序运行的时候,会被加载进入到JVM中,所以程序运行时可以获取到
2、@Target使用范围
指定了注解运用到的地方。类比作标签,原本标签是想贴到什么地方就贴到什么地方,但是有了@Target的存在,它张贴的地方就非常具体了,比如只能张贴到方法上、类上、方法参数上等
取值:
- ElementType.ANNOTATION_TYPE :可以给一个注解进行注解
- ElementType.CONSTRUCTOR :可以给构造方法进行注解
- ElementType.FIELD :可以给属性进行注解
- ElementType.LOCAL_VARIABLE :可以给局部变量进行注解
- ElementType.METHOD: 可以给方法进行注解
- ElementType.PACKAGE: 可以给一个包进行注解
- ElementType.PARAMETER :可以给一个方法内的参数进行注解
- ElementType.TYPE :可以给一个类型进行注解,比如类、接口、枚举
3、@Document保存到javadoc
@Documented 和文档有关系,能够将注解中的元素包含到Javadoc中
4、@Inherited注解继承
Inherited是继承的意思,但是它并不是说注解本身可以继承,而是说如果一个超类被@Inherited注解过的注解进行注解的话(注解了B注解,B在注解其他),那么它的子类没有被任何注解应用的话,那么这个子类就继承了超类的注解
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@interface Test {}
@Test
public class A {}
public class B extends A {}
三、如何实现的注解
四、问提:
注解的生命周期?
有三种:源文件阶段、字节码文件阶段、内存字节码阶段
1、注解被保留到源文件阶段
当javac把.java源文件编译成.class时,就将相应的注解去掉,这种注解的生命周期就维持到源文件阶段
2、注解被保留到字节码(.class)文件阶段(编译时)
在JVM通过ClassLoader向内存中加载字节码文件时,JVM会去掉相应的注解。这种注解的生命周期就维持到字节码文件阶段
3、注解被保留到内存中的字节码阶段(运行时)
JVM运行内存的i字节码时,仍然可能会保留并且执行的某些注解。这种注解的生命周期就维持到内存字节码阶段
三个阶段简单表示为:java源文件-->class文件-->内存中的字节码
五、自定义注解实现过程
1、定义自定义注解
2、在定义的自定义注解上方添加注解
3、使用注解
4、编写自定义注解解释器