反射可依据注解中声明的Class类型属性动态加载并实例化对应类的对象,即将注解里的Class值作为“类模板”通过反射创建实例;注解支持Class作为合法属性类型。

反射能根据注解中声明的 Class 类型属性,动态加载并实例化对应类的对象——关键在于把注解里的 Class 值当作“类模板”,再用反射创建其实例。
注解中定义 Class 类型属性
注解支持 Class 作为合法属性类型。例如:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Handler {
Class<? extends Executor> value(); // 指定执行器实现类
String desc() default "";
}
这里 value() 是一个泛型受限的 Class 属性,要求传入的必须是 Executor 的子类型。
使用时可这样标注:
@Handler(AsyncExecutor.class)
public void doTask() { ... }
运行时读取注解并获取 Class 对象
通过反射拿到方法上的注解后,直接调用其 value() 方法即可获得目标类的 Class 实例:
Method method = targetClass.getDeclaredMethod("doTask");
Handler handler = method.getAnnotation(Handler.class);
if (handler != null) {
Class<? extends Executor> executorClass = handler.value(); // ✅ 得到 Class 对象
}
注意:该 Class 对象已由 JVM 加载就绪,无需再调用 Class.forName;它本身就是可直接用于实例化的“类模板”。
用 Class 对象安全实例化执行器
拿到 executorClass 后,调用 newInstance() 或更推荐的构造器方式创建实例:
- 确保目标类有 public 无参构造器(否则
newInstance()报错) - 推荐显式获取构造器,增强可控性与兼容性(尤其 Java 9+ 中
newInstance()已弃用) - 若类含私有构造器,需配合
setAccessible(true)
try {
Constructor<? extends Executor> ctor = executorClass.getDeclaredConstructor();
ctor.setAccessible(true); // 如需访问私有构造器
Executor executor = ctor.newInstance();
executor.execute(); // 调用业务逻辑
} catch (Exception e) {
throw new RuntimeException("无法实例化执行器: " + executorClass, e);
}
为什么能直接用?Class 对象的本质
Class 对象不是字符串或占位符,而是 JVM 已加载的真实类型元数据载体。注解中写 AsyncExecutor.class,编译后该字节码就持有了对 AsyncExecutor 类的强引用;运行时反射读取时,返回的就是那个已加载、可直接操作的 Class<asyncexecutor></asyncexecutor> 实例。
它天然满足反射实例化的全部前提:
– 类已加载(编译期确定,运行时保证)
– 可获取构造器(getDeclaredConstructor)
– 可绕过访问限制(setAccessible)
– 可触发初始化(newInstance 或 constructor.newInstance)

















