使用反射处理注解
- 用反射除了可以在运行时动态地获取类的相关信息,例如类的所有方法、属性和构造方法,还可以创建对象、调用方法等,也可以获得注解的相关信息;
- 反射是在运行时获取相关信息的,因此要使用反射获取注解的相关信息,这个注解必须是用 @Rentention(RententionPolicy.RUNTIME) 声明的;
- java.lang.reflect.AnnotatedElement 接口中定义了使用反射读取注解信息的方法,详见:Interface AnnotatedElement;
1. 读取注解信息的方法
- Class 类、Constructor 类、Field 类、Method 类、Package 类都实现了 AnnotatedElement 接口,可以通过这些类的实例获取作用于其上的注解及相关信息;
类型 |
方法 |
说明 |
Annotation |
getAnnotation(Class annotationType) |
若存在该元素的指定类型的注解,则返回这些注解,否则,返回 null |
Annotation[ ] |
getAnnotations() |
返回此元素上存在的所有注解 |
Annotation[ ] |
getDeclaredAnnotations() |
返回该元素上已声明的所有注解,否则返回 null,使用该方法可以自由修改返回的数组 |
boolean |
isAnnotationPresent(Class annotationType) |
若指定类型的注解存在于此元素上,则返回 true,否则返回 false |
2. Java 实例
- 首先定义一个注解 UserAnno,并声明作用范围,定义了注解的属性 value,它的默认值是 user;
- 然后定义使用注解的类 AnnoClass,在类和类的方法上使用注解;
- 在类上使用注解时,使用注解属性的默认值;
- 在方法上使用注解时,显示对注解的属性赋值;
- Test 类利用反射获取注解信息;
import java.lang.annotation.*;
import java.lang.reflect.Method;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface UserAnno {
String value() default "user";
}
@UserAnno
class AnnoClass {
@UserAnno("方法-注解")
public void method() {
System.out.println("1");
}
}
public class Test {
public static void main(String[] args) {
try {
Class c = Class.forName("AnnoClass");
Class cUser = Class.forName("UserAnno");
Annotation anno = c.getAnnotation(cUser);
if (anno != null) {
UserAnno a = (UserAnno) anno;
System.out.println("AnnoClass 类上的注解:" + a.value());
}
Method m = c.getDeclaredMethod("method");
Annotation an = m.getAnnotation(cUser);
if (an != null) {
UserAnno a = (UserAnno) an;
System.out.println("method()方法上的注解:" + a.value());
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}