Java注解(Annotation)了解
注解【了解】
什么是注解
Java 注解(Annotation)又称 Java 标注,是 JDK5.0 引入的一种注释机制。
Java 注解是在 JDK5 时引入的新特性,注解(也被称为元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在稍后某个时刻非常方便地使用这些数据。注解类型定义指定了一种新的类型,一种特殊的接口类型。 在关键词 interface 前添加 @ 符号也就是用 @interface 来区分注解的定义和普通的接口声明。目前大部分框架(如 Spring Boot 等)都通过使用注解简化了代码并提高的编码效率。
JDK 中内置的注解
Java 定义了一套注解,其中
java.lang
包下
- @Override - 检查该方法是否是重写方法。如果发现其父类,或者是引用的接口中并没有该方法时,会报编译错误
- @Deprecated - 标记过时方法。如果使用该方法,会报编译警告
- @SuppressWarnings - 指示编译器去忽略注解中声明的警告
- @SafeVarargs - Java 7 开始支持,忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告
- @FunctionalInterface - Java 8 开始支持,标识一个匿名函数或函数式接口
java.lang.annotation
包下
- @Retention - 标识这个注解怎么保存,是只在代码中,还是编入 class 文件中,或者是在运行时可以通过反射访问
- @Documented - 标记这些注解是否包含在用户文档中
- @Target - 标记这个注解应该是哪种 Java 成员
- @Inherited - 标记这个注解是继承于哪个注解类(默认 注解并没有继承于任何子类)
- @Repeatable - Java 8 开始支持,标识某注解可以在同一个地方使用相同的注解
注解的本质
我们来看一个 JDK 内置的注解: @Override
定义
1 | package java.lang; |
这个注解的本质就是一个继承了 Annotation 接口的接口
1 | public interface Override extends Annotation{ |
元注解
在 JDK 1.5 中提供了 4 个标准的用来对注解类型进行注解的注解类,我们称之为 meta-annotation
(元注解), 这四个注解分别是
- @Documented – 注解是否将包含在 JavaDoc 中
- @Retention – 什么时候使用该注解
- @Target – 注解用于什么地方
- @Inherited – 是否允许子类继承该注解
@Retention
@Reteniton:指明当前注解的生命周期(即:用来限定那些被它所注解的注解类在注解到其他类上以后,可被保留到何时) 。
一共有三种策略,定义在 RetentionPolicy
枚举中。
1 | public enum RetentionPolicy { |
● SOURCE:在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override 就属于这类注解。
● CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式。
● RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。
@Target
@Target:描述注解的使用范围,默认值为任何元素。
它的取值范围定义在 ElementType
枚举中,可用的 ElementType
参数包括
1 | public enum ElementType { |
@Documented
@Documented 注解修饰的注解,当我们执行 JavaDoc 文档打包时会被保存进 doc 文档。
@Inherited
@Inherited:使被它修饰的注解具有继承性(也就说我们的注解修饰了一个类,而该类的子类将自动继承父类的该注解)。
自定义注解
格式
public @interface 注解名 {定义体}
- 权限修饰符只能为 public 或者默认缺省(default)
- 如果只有一个参数成员,最好把参数名称设为”value”,后加小括号
- 注解元素必须有确定的值,要么在定义注解的默认值中指定,要么在使用注解时指定,比如
String value() default "";
测试
自定义品牌注解,并设置默认值
1 |
|
定义一个实体类,这里用了 lombok
1 |
|
查看效果
1 | public class Demo { |