解析注解:通过反射获取类、函数或成员上的运行时注解信息,从而实现动态控制程序运行的逻辑
接下来我们通过一段代码来进行测试,看看到底什么是解析注解:
自定义一个注解Description:
package com.Annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD,ElementType.TYPE})//注解的作用域:CONSTRUCTOR FIELD LOCAL_VARIABLE METHOD PACKAGE PARAMETER TYPE
@Retention(RetentionPolicy.RUNTIME)//注解的声明周期:SOURCE CLASS RUNTIME
@Inherited//标识性注解:允许子注解来继承
@Documented//生成javadoc是会包含注解
public @interface Description{
String value();
int age() default 18;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
在Child类中使用该注解:
package com.notation;
@Description("i am class annotation")
public class Child implements Person {
//覆盖了父类的一个方法
@Override
@Description("i am method annotation")
public String name() {
// TODO Auto-generated method stub
return null;
}
@Override
public int age() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void sing() {
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
对Description进行解析:
package com.notation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
public class ParseAnn {
public static void main(String[] args) throws ClassNotFoundException {
//使用类加载器加载类
Class c=Class.forName("com.Annotation.Child");
//找到注解
boolean isExist=c.isAnnotationPresent(Description.class);
if(isExist) {
//拿到注解
Description a=(Description)(c.getAnnotation(Description.class));
System.out.println(a.value());
}
//找到方法上的所有注解
//遍历找到类中的所有方法
Method[] ms=c.getMethods();
for (Method method : ms) {boolean MExist=method.isAnnotationPresent(Description.class);
if(MExist) {
Description a=(Description)(method.getAnnotation(Description.class));
System.out.println(a.value());
}
}
for (Method method : ms) {
Annotation[] as=method.getAnnotations();
for (Annotation annotation : as) {
if(annotation instanceof Description) {
Description a=(Description)annotation;
System.out.println(a.value());
}
}
}
}
}
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
34
35
36
37
38
运行结果为:
i am class annotation
i am method annotation
i am method annotation
接下来我们来讨论一下注解的继承:
1、注解的继承是相对于类而言的,对于接口时无效的
2、注解只继承父类的类注解,不继承方法注解
将Person类变为:
package com.notation;
@Description("i am class interface")
public class Person {
@Description("i am method interface")
public String name() {
return null;
}
public int age() {
return 0;
}
@Deprecated
public void sing() {
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
将Child类改为:
package com.notation;
public class Child extends Person {
//覆盖了父类的一个方法
@Override
public String name() {
// TODO Auto-generated method stub
return null;
}
@Override
public int age() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void sing() {
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
运行结果为:
i am class interface
测试结果显示,子类只继承父类注解的类注解,没有继承其方法注解