Java注解
注解Annotation
// 自定义注解必须是在@interface
// 如下自定义注解Report
// default用于给注解参数设置默认值
public @interface Report {
int type() default 0;
String level() default "info";
// 最常用的参数命名为value
String value() default "";
}
元注解
元注解用于修饰其他注解的注解,java中定的元注解有@Target
、@Retention
、@Repeatable
、@Inherited
@Target
(使用场合)
最常用的注解,定义注解可被用于源码的哪些位置
- 类或接口:
ElementType.TYPE
; - 字段:
ElementType.FIELD
; - 方法:
ElementType.METHOD
; - 构造方法:
ElementType.CONSTRUCTOR
; - 方法参数:
ElementType.PARAMETER
。
使用实例:
// 当前Target注解指定Report注解只能用在方法上
@Target(ElementType.METHOD)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
// Target注解还可以是数组,只不过书写不是数组格式,而是采用{,}的形式罗列,如下表示Report注解可用于方法、类或接口
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface Report{
int type() default 0;
String level() default "info";
String value() default "";
}
@Retention
(使用周期)
定义了Annotation
的生命周期,若没有@Retention
注解,默认仅class
文件,即:RetentionPolicy.CLASS
,通常自定义的Annotation
都是RUNTIME,所以自定义注解务必加上@Retention(RetentionPolicy.RUNTIME)
注解
- 仅编译期:
RetentionPolicy.SOURCE
; - 仅class文件:
RetentionPolicy.CLASS
; - 运行期:
RetentionPolicy.RUNTIME
。
例子:
@Retention(RetentionPolicy.RUNTIME)
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
@Repeatable
(可重复)
定义注解是否可重复
例子:
定义:
// 子注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Repeatable(ActionUnlockChecks.class)
public @interface ActionUnlockCheck {
int actionType();
}
// 父注解
// 父注解必须有以下特征:
// 1:作用域必须大于等于子注解
// 2:父注解的周期要比子注解的周期要小或相同(注意:SOURCE(源码) < CLASS (字节码) < RUNTIME(运行))
// 3:父注解的value的类型是子注解类型的数组
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface ActionUnlockChecks {
ActionUnlockCheck[] value();
}
使用:
@Report(type=1, level="debug")
@Report(type=2, level="warning")
public class Hello {
}
通过如下java反射得到作用域RUNTIME
的注解
ActionUnlockCheck annotation = joinPoint.getTarget().getClass().getAnnotation(ActionUnlockCheck.class);
结果如下:
@ActionUnlockChecks({@ActionUnlockCheck(
actionType = 114
), @ActionUnlockCheck(
actionType = 113
)})
也就是说多个子注解其实会被转换成一个父注解
@Inherited
(继承)
定义子类是否可继承父类定义的注解,@Inherited
注解只对@Target(ElementType.TYPE)
类型注解有用,并且仅针对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 {
}
// 子类(子类继承该注解,即Student也定义了Report注解)
public class Student extends Person {
}
自定义注解
1、定义@interface
public @interface Report {
}
2、添加参数默认值
public @interface Report {
int type() default 0;
String level() default "info";
String value() default "";
}
3、元注解配置注解
@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