上篇介绍了注解的基本知识和自定义注解,这篇文章来介绍如何在运行时解析注解。通过反射可以获得一些注解的信息,根据这些信息就可以进行一些操作。

注解定义

要在运行时获得注解的信息,需要将注解的保留策略设置为RUNTIME。首先写一个测试用例。

1
2
3
4
5
6
7
8
9
10
11
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface Info {
String name();
String[] author();
String comment();
}

定义一个Info注解,适用于任何变量、类、方法,保留策略为运行时

然后需要一个被注解标注的类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Info(name = "class-InfoClass", author = { "sumy",
"noclyt" }, comment = "Use to holding username")
public class InfoClass {
@Info(name = "var-name", author = { "sumy" }, comment = "username")
private String name;
@Info(name = "<constructor>", author = {}, comment = "constructor")
public InfoClass(String name) {
this.name = name;
}
@Info(name = "method-getName", author = {
"noclyt" }, comment = "a method use to getting username")
public String getName() {
return name;
}
}

定义了一个类,并用注解为类和类中的成员标注了信息。

解析注解

上面已经定义好了注解和使用注解的类,下面尝试获取注解的信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class TestAnnotation {
public static void main(String[] args) {
// 获取类的注解信息
for (Annotation annotation : InfoClass.class.getAnnotations()) {
System.out.println("class annotation: " + annotation.toString());
}
// 获取变量的注解信息
for (Field field : InfoClass.class.getDeclaredFields()) {
// 遍历获取所有注解
for (Annotation anno : field.getDeclaredAnnotations()) {
System.out.println("field annotation: " + anno.toString());
}
}
// 获取方法的注解信息
for (Method method : InfoClass.class.getMethods()) {
if (method.isAnnotationPresent(Info.class)) { // 判断Info注解是否存在于这个方法
// 获取指定类型的注解
Info infoanno = method.getAnnotation(Info.class);
System.out.println("method annoation: " + infoanno.toString());
System.out.println(
"method " + method.getName() + "'s author(s) is/are "
+ Arrays.toString(infoanno.author()));
}
}
}
}

运行结果:

1
2
3
4
class annotation: @Info(name=class-InfoClass, author=[sumy, noclyt], comment=Use to holding username)
field annotation: @Info(name=var-name, author=[sumy], comment=username)
method annoation: @Info(name=method-getName, author=[noclyt], comment=a method use to getting username)
method getName's author(s) is/are [noclyt]

这样就通过基本的反射方法获取了注解信息。注解API非常强大,被广泛应用于各种Java框架,如Spring,Hibernate,JUnit等。

参考文献