目录
注解的解析
概述
什么是注解的解析?
- 就是判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来。
如何解析注解?
- 指导思想:要解析谁上面的注解,就应该先拿到谁。
- 比如要解析类上面的注解,则应该先获取该类的Class对象,再通过Class对象解析其上面的注解。
- 比如要解析成员方法上的注解,则应该获取到该成员方法的Method对象,再通过Method对象解析其上面的注解。
- Class、Method、Field、Constructor,都实现了AnnotatedElement接口,它们都拥有解析注解的能力。
AnnotatedElement接口提供了解析注解的方法 | 说明 |
---|---|
public Annotation[] getDeclaredAnnotations() | 获取当前对象上面的注解 |
public T getDeclaredAnnotation(Class<T> annotationClass) | 获取指定的注解对象 |
public boolean isAnnotationPresent(Class<Annotation> annotationClass) | 判断当前对象上是否存在某个注解 |
案例
解析注解的案例,具体需求如下:
①定义注解MyTest4,要求如:
- 包含属性:String value()
- 包含属性:double aaa(),默认值为100
- 包含属性:String[] bbb()
- 限制注解使用的位置:类和成员方法上
- 指定注解的有效范围:一直到运行时
②定义一个类叫:Demo,在类中定义一个test1方法,并在该类和其方法上使用MyTest4注解
③定义AnnotationTest3测试类,解析Demo类中的全部注解。
代码实例(1)
MyTest4注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME) //控制下面的注解一直保留到运行时
public @interface MyTest4 {
String value();
double aaa() default 100;
String[] bbb();
}
Demo类
@MyTest4(value = "蜘蛛精", aaa=99.5,bbb ={"至尊宝","铁扇公主"})
public class Demo {
@MyTest4(value = "孙悟空",aaa = 199.9,bbb = {"紫霞","牛夫人"})
public void test1(){
}
}
测试
import org.junit.Test;
import java.util.Arrays;
public class AnnotationTest3 {
@Test
public void parseClass(){
//1.先得到Class对象
Class c = Demo.class;
//2.解析类上的注解
//判断类上是否包含了某个注解
if(c.isAnnotationPresent(MyTest4.class)){
MyTest4 myTest4 =
(MyTest4) c.getDeclaredAnnotation(MyTest4.class);
System.out.println(myTest4.value());
System.out.println(myTest4.aaa());
System.out.println(Arrays.toString(myTest4.bbb()));
}
}
}
运行结果:
代码实例(2)
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.Arrays;
public class AnnotationTest3 {
@Test
public void parseClass() throws Exception{
//1.先得到Class对象
Class c = Demo.class;
//拿到要解析的方法
Method m = c.getDeclaredMethod("test1");
//2.解析方法上的注解
//判断方法对象上是否包含了某个注解
if(c.isAnnotationPresent(MyTest4.class)){
MyTest4 myTest4 =
(MyTest4) m.getDeclaredAnnotation(MyTest4.class);
System.out.println(myTest4.value());
System.out.println(myTest4.aaa());
System.out.println(Arrays.toString(myTest4.bbb()));
}
}
}
运行结果:
应用场景
需求与分析
模拟Junit框架
需求
- 定义若干个方法,只要加了MyTest注解,就会触发该方法执行。
分析
- 定义一个自定义注解MyTest,只能注解方法,存活范围是一直都在。
- 定义若干个方法,部分方法加上@MyTest注解修饰,部分方法不加。
- 模拟一个junit程序,可以触发加了@MyTest注解的方法执行。
代码实例(3)
MyTest注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) //注解只能用在方法上
@Retention(RetentionPolicy.RUNTIME)
public @interface MyTest {
}
AnnotationTest4类
public class AnnotationTest4 {
public void test1(){
System.out.println("===test1===");
}
@MyTest
public void test2(){
System.out.println("===test2===");
}
public void test3(){
System.out.println("===test3===");
}
@MyTest
public void test4(){
System.out.println("===test4===");
}
}
main
import java.lang.reflect.Method;
public class myJunit {
public static void main(String[] args) throws Exception {
AnnotationTest4 a = new AnnotationTest4();
//启动程序
//1.得到Class对象
Class c = AnnotationTest4.class;
//2.提取这个类中的全部成员方法
Method[] methods = c.getDeclaredMethods();
//3.遍历这个数组中的每个方法,看方法上是否存在@MyTest注解
//存在则触发该方法
for(Method method:methods){
if(method.isAnnotationPresent(MyTest.class)){
//说明当前方法上是存在@MyTest,触发当前方法执行
method.invoke(a);
}
}
}
}
运行结果:
END
学习自:黑马程序员——Java课程