题目
使用反射读取方法上的注解并执行方法
信息
- 类型:问答
- 难度:⭐
考点
注解定义,反射获取方法,反射调用方法,注解信息读取
快速回答
实现步骤:
- 定义运行时注解
@TestAnnotation - 在目标方法上添加该注解
- 通过反射获取类中所有方法
- 遍历方法检查是否存在
@TestAnnotation - 使用
method.invoke()执行带注解的方法
原理说明
Java反射允许在运行时检查类、方法和注解等信息。注解需要设置 @Retention(RetentionPolicy.RUNTIME) 才能在运行时被反射读取。通过 Class.getDeclaredMethods() 获取方法,再使用 method.getAnnotation() 检查注解存在性,最后用 method.invoke() 执行方法。
代码示例
// 1. 定义运行时注解
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@interface TestAnnotation {
String value() default "";
}
// 2. 目标类
class MyClass {
@TestAnnotation("重要方法")
public void annotatedMethod() {
System.out.println("带注解的方法被执行");
}
public void normalMethod() {
System.out.println("普通方法");
}
}
// 3. 反射读取注解并执行方法
public class AnnotationProcessor {
public static void main(String[] args) throws Exception {
Class<?> clazz = MyClass.class;
Object instance = clazz.getDeclaredConstructor().newInstance();
for (Method method : clazz.getDeclaredMethods()) {
// 4. 检查方法是否有TestAnnotation
if (method.isAnnotationPresent(TestAnnotation.class)) {
TestAnnotation annotation = method.getAnnotation(TestAnnotation.class);
System.out.println("发现带注解方法: " + method.getName() + ", 注解值: " + annotation.value());
// 5. 执行方法
method.invoke(instance);
}
}
}
}
最佳实践
- 始终检查方法可访问性:使用
method.setAccessible(true)处理私有方法 - 异常处理:捕获
InvocationTargetException和IllegalAccessException - 性能考虑:反射调用比直接调用慢,避免在性能敏感场景滥用
常见错误
- 忘记设置
@Retention(RetentionPolicy.RUNTIME)导致注解运行时不可见 - 未处理
IllegalAccessException(如尝试调用私有方法未设置setAccessible(true)) - 混淆
getDeclaredMethods()(获取所有方法)和getMethods()(仅获取public方法)
扩展知识
- 注解生命周期:
SOURCE(编译期丢弃)、CLASS(类文件保留)、RUNTIME(运行时保留) - 框架应用:Spring的
@Autowired、JUnit的@Test均基于此机制实现 - 替代方案:Java 8+ 可使用
MethodHandlesAPI 进行更高效的操作