Java反射获取Class<?>后如何调用带泛型约束的自定义函数
方案1:简化泛型约束(更推荐,降低后续使用成本)
原有递归嵌套的泛型约束过于冗余,可调整为以下形式,既保留基础类型安全,又减少反射调用的强转开销:
// 调整父类泛型约束,去掉互相嵌套的递归规则 public abstract class Parent<E extends Extendable<?>> { } public abstract class Extendable<P extends Parent<?>> { } // 业务类无需修改 public class MyParent extends Parent<MyExtendable> { protected class MyExtendable extends Extendable<MyParent> { } } // 同步简化函数泛型定义 // 注:你原有代码传参是Class对象,这里修正了第二个参数的类型,如果你确实需要传Extendable实例可自行调整 <E extends Extendable<?>> void genericFunction(Class<? extends Parent<E>> parentClass, Class<E> extendableClass) { // 原有业务逻辑不变 }
调用时直接做安全强转即可,你已经确认所有扫描到的类符合约束,直接加@SuppressWarnings("unchecked")消除编译警告即可:
@SuppressWarnings("unchecked") ClassPath.from(MyParent.class.getClassLoader()) .getTopLevelClasses() .forEach(classInfo -> { // 原有检查逻辑 Class<?> clazz = classInfo.load(); Class<? extends Parent<?>> parentClazz = (Class<? extends Parent<?>>) clazz; for (Class<?> declaredClass : clazz.getDeclaredClasses()) { Class<? extends Extendable<?>> extendableClazz = (Class<? extends Extendable<?>>) declaredClass; genericFunction((Class) parentClazz, (Class) extendableClazz); } });
方案2:保留原有泛型,直接反射调用方法
如果不想修改现有泛型定义,可以直接反射执行目标方法,完全绕过编译期泛型检查:
// 先获取目标方法对象,假设genericFunction定义在当前类TestClass中,第二个参数是Extendable实例类型 Method method = TestClass.class.getDeclaredMethod("genericFunction", Class.class, Extendable.class); method.setAccessible(true); ClassPath.from(MyParent.class.getClassLoader()) .getTopLevelClasses() .forEach(classInfo -> { // 原有检查逻辑 Class<?> clazz = classInfo.load(); for (Class<?> declaredClass : clazz.getDeclaredClasses()) { try { // 非静态内部类实例化需要传入外部类实例 Object parentInstance = clazz.newInstance(); Object extendableInstance = declaredClass.getConstructor(clazz).newInstance(parentInstance); // 方法如果是静态方法,第一个参数传null即可 method.invoke(this, clazz, extendableInstance); } catch (Exception e) { // 自行处理异常 e.printStackTrace(); } } });
注意:你的内部类
MyExtendable是非静态内部类,反射创建实例时必须先构造外部类对象,再传入内部类构造方法,不能直接调用无参newInstance()。
内容的提问来源于stack exchange,提问作者Steam gamer
相关产品推荐
相关产品推荐

