定义注解
约 651 字大约 2 分钟
2024-08-08
Java语言使用 @interface 语法来定义注解(Annotation)
定义步骤
第一步,用 @interface 定义注解
public @interface Report {
}第二步,添加参数、默认值
public @interface Report {
int type() default 0;
String level() default "info";
// 把最常用的参数定义为value(),推荐所有参数都尽量设置默认值。
String value() default "";
}第三步,用元注解配置注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}其中,必须设置 @Target 和 @Retention,@Retention 一般设置为 RUNTIME,因为我们自定义的注解通常要求在运行期读取。一般情况下,不必写 @Inherited 和 @Repeatable
元注解
有一些注解可以修饰其他注解,这些注解就称为元注解(meta annotation)。Java标准库已经定义了一些元注解,我们只需要使用元注解,通常不需要自己去编写元注解
@Target
最常用的元注解是 @Target。使用 @Target 可以定义 Annotation 能够被应用于源码的哪些位置
类或接口:
ElementType.TYPE字段:
ElementType.FIELD方法:
ElementType.METHOD构造方法:
ElementType.CONSTRUCTOR方法参数:
ElementType.PARAMETER
定义注解 @Report 可用在方法上,我们必须添加一个 @Target(ElementType.METHOD)
@Target(ElementType.METHOD)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}定义注解 @Report 可用在方法或字段上,可以把 @Target 注解参数变为数组 { ElementType.METHOD, ElementType.FIELD }
@Target({
ElementType.METHOD,
ElementType.FIELD
})
public @interface Report {
...
}@Retention
另一个重要的元注解 @Retention 定义了 Annotation 的生命周期
仅编译期:
RetentionPolicy.SOURCE仅
class文件:RetentionPolicy.CLASS运行期:
RetentionPolicy.RUNTIME
如果 @Retention 不存在,则该 Annotation 默认为 CLASS。因为通常我们自定义的 Annotation 都是 RUNTIME,所以,务必要加上 @Retention(RetentionPolicy.RUNTIME) 这个元注解
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}@Repeatable
使用 @Repeatable 这个元注解可以定义 Annotation 是否可重复。这个注解应用不是特别广泛
@Repeatable(Reports.class)
@Target(ElementType.TYPE)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}经过 @Repeatable 修饰后,在某个类型声明处,就可以添加多个 @Report 注解
@Report(type=1, level="debug")
@Report(type=2, level="warning")
public class Hello {
}@Inherited
使用 @Inherited 定义子类是否可继承父类定义的 Annotation。@Inherited 仅针对 @Target(ElementType.TYPE) 类型的 annotation 有效,并且仅针对 class 的继承,对 interface 的继承无效
@Inherited
@Target(ElementType.TYPE)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}在使用的时候,如果一个类用到了 @Report
@Report(type=1)
public class Person {
}则它的子类默认也定义了该注解
public class Student extends Person {
}