1注解
使用@interface定义注解(Annotation):
- 注解的参数类似无参数方法
- 可以设定一个默认值(推荐)
- 把最常用的参数命名为value(推荐)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
2元注解(meta annotation)
一个是Target,一个是Rentention
使用@Target定义Annotation可以被应用于源码的那些位置
- 类或接口:ElementType.TYPE
- 字段:ElementType.FIELD
- 方法:ElementType.METHOD
- 构造方法:ElementType.CONSTRUCTOR
- 方法参数:ElementType.PARAMETER
@Target({
ElementType.METHOD,
ElementType.FIELD
})//可以传入一个或多个,该段表示可以应用于字段和方法中
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
使用@Retention定义Annotation的生命周期:
- 仅编译期:RetentionPolicy.SOURCE,编译器在编译时直接丢弃,不会保存到class文件中
- 仅class文件:Retention.CLASS,该Annotation仅存储在class文件中,不会被读取
- 运行期:Retention.RUNTIME,在运行期可以读取该Annotation
如果@Retention不存在,则该Annotation默认为CLASS,通常自定义的Annotation都是RUNTIME
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
使用@Repeatable定义Annotation是否可重复
- JDK >= 1.8
@Repeatable
@Target(ElementType.TYPE)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
@Report(type=1,level="debug")
@Report(type=2,level="warning")
public class Hello{
}
使用@Inherited定义子类是否可继承父类定义的Annotation
- 仅针对@Target为TYPE类型的Annotation
- 仅针对class的继承
- 对interface的继承无效
@Inherited
@Target(ElementType.TYPE)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
@Report(type=1)
public class Person{
}
public class Student extends Person{
}
定义Annotation的步骤:
- 用@interface定义注解
- 用元注解(meta annotation)配置注解
- Target:必须设置
- Retention:一般设置为RUNTIME
- 通常不必写@Inherited,@Repeatable等等
- 定义注解参数和默认值
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
3代码演示
//第一个注解,表示字段和参数不能为空
@Target({ElementType.FIELD,ElementType.PARAMETER})
public @interface NotNull {
}
//第二个注解,表示1-100的范围
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Range {
int min() default 1;
int max() default 100;
}
public class Person {
@NotNull
public String name;
@Range(max = 20)//注解最大值为20
public int age;
public Person(@NotNull String name,int age) {//name不能为空
this.name = name;
this.age = age;
}
}
4总结
- 使用@interface定义注解
- 可定义多个参数和默认值,核心参数使用value名称
- 必须设置@Target来指定Annotation可以应用的范围
- 应当设置@Retention为RUNTIME便于运行期读取该Annotation