注解解析与应用场景
1.注解解析
- 注解解析就是判断类上、方法上、成员变量上是否存在注解,并把注解里的内容给解析出来
2.如何解析注解?
- 思想:要解析谁上面的注解,就应该先拿到谁(通过反射)
- 如果要解析类上面的注解,则应该先获取该类的Class对象,再通过Class对象解析其上面的注解
- 如果要解析成员方法上的注解,则应该获取到该成员方法的Method对象,再通过Method对象解析其上面的注解
- Class、Method、Field、Constructor都实现了AnnotatedElement接口,它们都拥有解析注解的能力
AnnotatedElement接口提供了解析注解的方法 | 说明 |
---|---|
public Annotation[] getDeclaredAnnotaions() | 获取当前对象上面的注释 |
public T getDeclaredAnnotaion(Class< T > annotationClass) | 获取指定的注解对象 |
public boolean isAnnotationPresent(Class< Annotation > annotationClass) | 判断当前对象上是否存在某个注解 |
java
public class MyAnnotationTest{
@Test
public void parseMethod() throws Exception { //解析方法上的注解
//获取Class对象
Class clazz = Demo.class;
//获取Method对象
Method method = clazz.getDeclaredMethod("test");
//判断Method对象上是否包含MyAnnotation注解
if(method.isAnnotationPresent(MyAnnotation.class)){
//获取指定的注解对象
MyAnnotation myAnnotation = (MyAnnotation) method.getDeclaredAnnotation(MyAnnotation.class);
//强转后打印信息
System.out.println(myAnnotation.value()); //李四
System.out.println(myAnnotation.age()); //28
System.out.println(myAnnotation.address()); //北京
}
}
@Test
public void parseClass(){ //解析类上的注解
//获取Class对象
Class clazz = Demo.class;
//判断Class对象上是否包含MyAnnotation注解
if(clazz.isAnnotationPresent(MyAnnotation.class)){
//获取指定的注解对象
MyAnnotation myAnnotation = (MyAnnotation) clazz.getDeclaredAnnotation(MyAnnotation.class);
//强转后打印信息
System.out.println(myAnnotation.value()); //张三
System.out.println(myAnnotation.age()); //20
System.out.println(myAnnotation.address()); //西安
}
}
}
/*
定义Demo类,并使用定义注解MyAnnotation修饰(属性值自拟)
*/
@MyAnnotation(value = "张三", age = 20, address = "西安")
class Demo {
//Demo类中定义test方法,并使用定义注解MyAnnotation修饰(属性值自拟)
@MyAnnotation(value = "李四", age = 28, address = "北京")
public void test(){
}
}
@Target({ElementType.TYPE, ElementType.METHOD}) //类和成员方法上
@Retention(RetentionPolicy.RUNTIME) //保留到运行阶段
@interface MyAnnotation {
String value();
int age() default 18;
String address();
}
3.应用场景
模拟Junit程序(提供main方法),运行后能自动触发加了@MyTest注解的所有方法
需求:定义若干个方法,只要加了MyTest注解,就会触发该方法执行
分析
- 定义一个自定义注解MyTest,只能标注在方法上,存活范围一直都在
- 定义若干个方法,部分方法加上@MyTest注解修饰,部分方法不加
- 模拟一个Junit程序,可以触发加了@MyTest注解的方法执行
java
public class Demo {
public static void main(String[] args) throws Exception {
//获取Demo类的Class对象
Class clazz = Demo.class;
//获取所有Method对象
Method[] methods = clazz.getDeclaredMethods();
//遍历获取每一个Method对象
for (Method method : methods) {
//方法上如果声明了@MyTest注解
if (method.isAnnotationPresent(MyTest.class)) {
//运行该方法,参数是空参构造创建的对象
method.invoke(clazz.getConstructor().newInstance());
}
}
}
//2、定义若干个方法,在想执行的方法上声明@MyTest注解
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执行了...");
}
}
//1、自定义注解@MyTest,只能注解方法,存活范围直到RUNTIME
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface MyTest {
}