Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
Java 语言中的类、方法、变量、参数和包等都可以被标注。和 Javadoc 不同,Java 标注可以通过反射获取标注内容。在编译器生成类文件时,标注可以被嵌入到字节码中。Java 虚拟机可以保留标注内容,在运行时可以获取到标注内容 。 当然它也支持自定义 Java 标注。
注解,和反射一样,是Java中最重要却最容易被人遗忘的知识点。哪怕Spring、SpringMVC、SpringBoot等框架中充满了注解,我们还是选择性地忽视它。很多人不明白它是怎么起作用的,甚至有人把它和注释混淆...工作中也只是机械性地在Controller上加@RequestMapping。是的,我们太习以为常了,以至于觉得它应该就是如此。
内容介绍
- 注解的作用
- 注解的本质
- 反射注解信息
- 元注解
- 自定义注解
注解的作用
- 格式检查: 告诉编译器信息,比如被@Override标记的方法如果不是父类的某个方法,IDE会报错;
- 减少配置: 运行时动态处理,得到注解信息,实现代替配置文件的功能;
- 减少重复工作: 比如第三方框架xUtils,通过注解@ViewInject减少对findViewById的调用,类似的还有(JUnit、ActiveAndroid等);
注解的本质
「java.lang.annotation.Annotation」接口中有这么一句话,用来描述『注解』。
The common interface extended by all annotation types
所有的注解类型都继承自这个普通的接口(Annotation)
复制代码
JDK 内置注解的定义:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
复制代码
这是注解 @Override 的定义,其实它本质上就是:
public interface Override extends Annotation{
}
复制代码
注解就像一个标签,是贴在程序代码上供另一个程序读取的。所以三者关系是:定义注解,使用注解,读取注解
反射注解信息
反射获取注解信息:
控制台:抛异常——注解MyAnnotation并没有为反射保留。
我们说过,注解本质上是继承了 Annotation 接口的接口,而当你通过反射,也就是我们这里的 getAnnotation 方法去获取一个注解类实例的时候,其实 JDK 是通过动态代理机制生成一个实现我们注解(接口)的代理类。
元注解
『元注解』是用于修饰注解的注解,通常用在注解的定义上,例如:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
复制代码
- @Target:加在注解上,限定该注解的使用位置。如果需要限定注解的使用位置,可以在自定义的注解上使用该注解。我们本次默认即可,不特别限定。
- @Target:注解的作用目标
- @Retention:注解的生命周期
- @Documented:注解是否应当被包含在 JavaDoc 文档中
- @Inherited:是否允许子类继承该注解
自定义注解
使用@interface自定义注解时,自动继承了java.lang.annotation.Annotation接口,由编译程序自动完成其他细节。在定义注解时,不能继承其他的注解或接口。@interface用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型(返回值类型只能是基本类型、Class、String、enum)。可以通过default来声明参数的默认值。
自定义注解格式:
元注解
public @interface 注解名{
定义体;
}
复制代码
- 注解参数可支持的数据类型:
1、所有基本数据类型(int,float,boolean,byte,double,char,long,short);
2、String类型;
3、Class类型;
4、enum类型;
5、Annotation类型;
6、以上所有类型的数组。