Java反射无法找到带泛型参数的继承方法问题排查
Java反射找不到泛型父类继承方法的问题解决
问题重现
有如下泛型父类和子类:
class Foo<X> { X name; public X getName() { return name; } public void setName(X name) { this.name = name; } } class Bar extends Foo<String> { }
当调用反射代码获取子类的setName方法时:
Bar.class.getMethod("setName", String.class)
会抛出NoSuchMethodException。
问题原因
这是Java泛型擦除机制导致的:
- Java泛型是编译期特性,编译完成后泛型类型信息会被擦除,
Foo类中的setName(X)会被处理成setName(Object)。 Bar继承Foo<String>后,编译器会自动生成一个隐式的桥接方法setName(String),但这个方法并非直接继承自Foo,而是编译器为了类型安全生成的包装方法。Class.getMethod()方法只会查找类直接声明的方法,或者继承来的、参数类型完全匹配的方法。但继承自Foo的setName参数类型是Object,和传入的String.class不匹配,因此找不到目标方法。
解决方案
方案一:通过父类获取方法后调用
既然Foo的setName实际参数类型是Object,直接从父类获取方法,调用时传入String对象即可(运行时类型兼容):
Method method = Foo.class.getMethod("setName", Object.class); method.invoke(new Bar(), "hello");
方案二:遍历所有方法筛选目标方法
遍历子类的所有公共方法,筛选出名称为setName且参数可接受String的方法:
Method targetMethod = null; for (Method method : Bar.class.getMethods()) { if ("setName".equals(method.getName()) && method.getParameterCount() == 1) { Class<?> paramType = method.getParameterTypes()[0]; if (paramType.isAssignableFrom(String.class)) { targetMethod = method; break; } } } if (targetMethod != null) { targetMethod.invoke(new Bar(), "hello"); }
方案三:解析泛型父类的实际类型(精确匹配)
如果需要严格对应泛型指定的实际类型,可以先解析子类的泛型父类信息,确认类型后再获取方法:
// 获取Bar的泛型父类类型 ParameterizedType superType = (ParameterizedType) Bar.class.getGenericSuperclass(); // 获取泛型参数X的实际类型 Class<?> actualType = (Class<?>) superType.getActualTypeArguments()[0]; // 确认实际类型是String后,调用父类方法 if (actualType == String.class) { Method method = Foo.class.getMethod("setName", Object.class); method.invoke(new Bar(), "hello"); }
内容的提问来源于stack exchange,提问作者eastwater
相关产品推荐
相关产品推荐

