定义注解
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 {
}