使用注解
- 注释会被编译器直接忽略
- 注解可以被编译器打包进入class文件
- 注解是一种用作标注的元数据
注解的作用
- 第一类: 是用编译器使用, (不会进入
.class
文件, 编译后就被忽略了)@Override
: 让编译器检查是否实现了覆写@SuppressWarnings
: 告诉编译器忽略此处代码产生的警告
- 第二类: 由工具处理
.class
文件使用的注解.- 某些工具加载class的时候, 对class做动态修改, 实现一些特殊的功能.
- 不会被编译进入
.class
文件, 加载结束后并不会存在内存中. - 这类注解只会被一些底层使用, 一般不会让我们处理
- 第三类: 程序运行期间能够读取的注解.
- 加载后一直存在于JVM.
@PostConstruct
, 在调用构造方法后自动调用- Java代码肚子该注解实现的功能, JVM不会标识
定义注解
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
元注解
-
可以修饰其他注解的注解: 元注解.
-
@Target: 标识元注解用于哪些位置
@Target(ElementType.METHOD)
@Target({ElementType.METHOD, ElementType.FIELD})
-
@Retention: 定义了注解的声明周期
@Retention(RetentionPolicy.RUNTIME)
-
@Repeatable: 定义是否可以重复.
-
@Inherited: 定义子类是否可以继承父类定义的
Annotation
如何定义Annotation
- 使用
@interface
定义注解 - 添加参数添加默认值
- 最常用的参数定义为
value()
- 并给所有参数一个默认值
- 最常用的参数定义为
- 元注解配置注解
- 必须设置
@Target
和@Retention
@Retention
一般设置为RUNTIME
: 因为我们自定义的注解通常要求在运行时读取- 一般情况下: 不必写
@Inherited
和@Repeatable
- 必须设置
处理注解
- 注解本身对代码逻辑没有任何影响
@Retention
的配置SOURCE
: 在编译器丢掉, 我们只使用不编写CLASS
: 仅保存在class文件中, 不会被加载到JVM, 涉及到class加载, 我们很少用RUNTIME
: 会被加载到JVM, 在程序运行期间可以被读取. 经常使用
- 注解可以读取:
Person.class.isAnnotationPresent(Report.class)
- 反射api读取:
Person.class.getAnnotation(Report.class)
- 获取方法注解的参数, 需要使用一个二维数组
具体使用注解
- 注解如何使用, 由程序决定
- JUnit会自动运行
@Test
标记的测试方法 - 使用举例:
- 使用的时候, 检查啥, 获取啥
- 然后再获取注解
- 对比下, 获取的, 是否符合注解
疑问
- 不理解
@Target(ElementType.TYPE)
什么意思?