Java自定义注解
定义
注解是一种能被添加到java源代码中的元数据(描述数据的数据),是一种程序特定的标注,可利用反射来实现动态功能映射。
example:
自定义注解接口
@Documented
@Inherited
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Init {
String value() default "";
String color();
}
public class Lion {
@Init(color = "yellow")
private String coat;
}
定义注解
- 定义成员
String value();
/**
* 成员类型 成员名称
**/
- 定义注解使用程序元素种类
@Target 定义注解类型
枚举常量 | 说明 |
---|---|
ANNOTATION_TYPE | 表示用于annotation(注解)类型 |
TYPE | 表示用于类、接口和枚举,以及annotation类型 |
CONSTRUCTOR | 表示用于构造方法 |
FIELD | 表示用于成员变量和枚举常量 |
METHOD | 表示用于方法 |
PARAMETER | 表示用于参数 |
LOCAL_VARIABLE | 表示用于局部变量 |
PACKAGE | 表示用于包 |
@RETENTION设置ANNOTATION的有效范围,默认为枚举常量CLASS。
枚举常量 | 说明 |
---|---|
SOURCE | 表示不编译Annotation到类文件中,有效范围最小 |
CLASS | 表示编译Annotation到类文件中,运行时不加载到JVM中 |
RUNTIME | 表示运行时加载到JVM中 ,有效范围最大 |
实例
设置字段 注解 其中,一个为字段值,一个为字段类型
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface Init {
String value() default "";
Class type() default void.class;
}
设置 构造参数 注解,方法描述
@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface LionConstructor {
String describe() default "default constructor";
}
使用注解,新建一个类
public class Lion {
@Init(value = "1001", type = int.class)
private int code;
@Init(value = "南美洲狮子", type = String.class)
private String name;
@LionConstructor(describe = "设置狮子种类的编号和昵称")
public Lion(@Init(value = "编号", type = int.class) int code, @Init(value = "名称", type = String.class) String name) {
this.code = code;
this.name = name;
}
@Init(value = "得到编号", type = int.class)
public int getCode() {
return code;
}
@Init(value = "设置编号", type = int.class)
public void setCode(@Init(value = "编号", type = int.class) int code) {
this.code = code;
}
@Init(value = "得到名称", type = String.class)
public String getName() {
return name;
}
@Init(value = "设置名称", type = String.class)
public void setName(@Init(value = "名称", type = String.class) String name) {
this.name = name;
}
}
利用反射获取注解值
public class LionFactory {
public static void main(String[] args) {
Class<Lion> lion = Lion.class;
// 通过反射获取构造方法
Constructor<?>[] declaredConstructors = lion.getDeclaredConstructors();
for (Constructor<?> declaredConstructor : declaredConstructors) {
System.out.println("获取构造参数"+declaredConstructor.getName()+"注解值");
// 查看是否有lionContructor的注解
if (declaredConstructor.isAnnotationPresent(LionConstructor.class)){
LionConstructor annotation = declaredConstructor.getAnnotation(LionConstructor.class);
System.out.println(annotation.describe());
}
Annotation[][] parameterAnnotations = declaredConstructor.getParameterAnnotations();
for (int i = 0; i < parameterAnnotations.length; i++) {
int length = parameterAnnotations[i].length;
// 没有添加参数注解
if (length == 0)
continue;
for (int j = 0; j < length; j++) {
Init init = (Init) parameterAnnotations[i][j];
System.out.println("参数值"+init.value()+" 参数类型"+init.type());
}
}
}
System.out.println("获取字段注解值");
Field[] declaredFields = lion.getDeclaredFields();
for (Field declaredField : declaredFields) {
// 查看是否有Init的注解
if (!declaredField.isAnnotationPresent(Init.class))
continue;
Init annotation = declaredField.getAnnotation(Init.class);
System.out.println(annotation.value());
}
/**
* 获取构造参数com.lion.tool.annotation.Lion注解值
* 设置狮子种类的编号和昵称
* 参数值编号 参数类型int
* 参数值名称 参数类型class java.lang.String
* 获取字段注解值
* 1001
* 南美洲狮子
*/
}
}