参考文章
https://juejin.im/post/5aa8bb61f265da239c7b0d55
什么是注解
首先注解主要分为三类:
类型 | 特点 |
---|---|
标准 Annotation | 包括 Override, Deprecated, SuppressWarnings,是java自带的几个注解,他们由编译器来识别,不会进行编译, 不影响代码运行,至于他们的含义不是这篇博客的重点,这里不再讲述。 |
元 Annotation | @Retention, @Target, @Inherited, @Documented,它们是用来定义 Annotation 的 Annotation。也就是当我们要自定义注解时,需要使用它们。 |
自定义 Annotation | 根据需要,自定义的Annotation。而自定义的方式 |
自定义注解
Retention
可选 | 特点 |
---|---|
RetentionPolicy.SOURCE | 源码时注解,一般用来作为编译器标记。如Override, Deprecated, SuppressWarnings。 |
RetentionPolicy.RUNTIME | 运行时注解,在运行时通过反射去识别的注解。 |
RetentionPolicy.CLASS | 编译时注解,在编译时被识别并处理的注解。 |
Target
可选 | 特点 |
---|---|
ElementType.TYPE | 类、接口、注解类型或枚举 |
ElementType.FIELD | 属性 |
ElementType.METHOD | 方法 |
ElementType.PARAMETER | 用于描述参数 |
ElementType.CONSTRUCTOR | 构造方法 |
ElementType.LOCAL_VARIABLE | 局部变量 |
ElementType.ANNOTATION_TYPE | 注解类 |
ElementType.PACKAGE | 包 |
@interface
@interface并不是说ContentView是一个接口,而是声明注解。
就像申明类用关键字class一样。申明注解用的就是@interface。
(值得注意的是:在ElementType的分类中,class、interface、Annotation、enum同属一类为Type,并且从官方注解来看,似乎interface是包含@interface的)
运行时注解
在运行时根据注解,通过反射获取具体信息,然后做一些操作。
(所以也会带来一定的性能开销)
- 声明注解
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface PrintView {
int value();
}
- 查找注解,并输出
public class Parent {
public void create() {
//注解解析
PrintView annotation = this.getClass().getAnnotation(PrintView.class);
if (annotation != null) {
try {
int value = annotation.value();
System.out.println("查找到的值 -> " + value);
} catch (RuntimeException e) {
e.printStackTrace();
}
}
}
}
- 使用注解
@PrintView(12345)
public class Child extends Parent {}
public class main {
public static void main(String[] args) {
Child child = new Child();
child.create();
}
}
// 输出
// 查找到的值 -> 12345