一般使用自定义注解有三大步骤:
- 首先自定义注解;
- 在代码中使用自定义的注解;
- 通过注解获取信息。
自定义注解的过程中一般会使用到@Target和@Retention,其中:
- @Retention的作用是描述注解的生命周期
取值 | 作用 |
---|---|
SOURCE | 在源文件中有效(即在源文件中保留) |
CLASS | 在class文件中有效(即在class文件中保留) |
RUNTIME | 在运行时有效,可以被反射机制读取 |
- @Target的作用是表示注解可以用在什么地方(作用范围)
取值 | 所修饰的范围 |
---|---|
PACKAGE | 包 |
TYPE | 类,接口,枚举,Annotation类型 |
CONSTRUCTOR | 用于描述构造器 |
FIELD | 用于描述域 |
METHOD | 用于描述方法 |
LOCAL_VARIABLE | 用于描述局部方法 |
PARAMETER | 用于描述参数 |
举个栗子,分别写一个自定义注解用于类和域上:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Exa {
String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ExaField {
String name(); //在数据库中的域名
String type(); //数据库中的类型名
int len(); //数据库中的长度
}
第二步,用于Student类上:
@Exa("stu_table")
public class Student {
@ExaField(name = "id", type = "int", len = 20)
int id;
@ExaField(name = "name", type = "varchar", len = 50)
String name;
@ExaField(name = "age", type = "int", len = 10)
int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
第三步,反射获取注解
public class Demo {
public static void main(String[] args) {
try {
Class clz = Class.forName("Exe.Student");
//获取类的所有注解
Annotation[] annotations = clz.getAnnotations();
for (Annotation annotation : annotations) {
System.out.println(annotation);
}
//获取指定的注解
Exa exa = (Exa) clz.getAnnotation(Exa.class);
System.out.println(exa.value());
//获取类属性的注解
Field f = clz.getDeclaredField("name");
ExaField exaField = f.getAnnotation(ExaField.class);
System.out.println(exaField.name() + "->" + exaField.type() + "->" + exaField.len());
} catch (Exception e) {
e.printStackTrace();
}
}
}
运行结果为:
@Exe.Exa(value="stu_table")
stu_table
name->varchar->50