使用注解
- 注释会被编译器直接忽略
- 注解可以被编译器打包进入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)什么意思?