我知道我试图做的事情在纯java中是不可能的——只有当我查看调试信息时才有可能。无论如何,我不会在没有调试的情况下进行编译,因为我的springmvc的buch将停止工作。
也就是说,我有以下情况:
一个通用超类:
软件包com.cinefms.apitester.springmvc.craclers;
public class TestGenerics<T extends TestGenericsInterface> {
public T get() {
return null;
}
public T put(T t) {
return null;
}
}
及其子类:
package com.cinefms.apitester.springmvc.crawlers;
public class TestGenericsSub extends TestGenerics<TestGenericsImpl> {
}
里面的东西真的很简单。
一个接口:
package com.cinefms.apitester.springmvc.crawlers;
public interface TestGenericsInterface {
}
及其实现:
package com.cinefms.apitester.springmvc.crawlers;
public class TestGenericsImpl implements TestGenericsInterface {
}
eclipse很好地计算出TestGenericsSub.get()
应该返回TestGenericsImpl
的实例。。。即使没有可用的源。
但是我怎么可能在运行时自己解决这个问题呢?
如果"m"是方法"run",则
m.getGenericReturnType();
会返回"T"(没有帮助),而:
m.getReturnType();
给了我"TestGenericsInterface"(也没有帮助)。我一直在看"org.javaruntype"库。。。但我似乎想不通。
有人能解释一下吗?
谢谢!
您可以使用ClassMate:实现这一点
TypeResolver typeResolver = new TypeResolver();
MemberResolver memberResolver = new MemberResolver(typeResolver);
ResolvedType resolvedType = typeResolver.resolve(TestGenericsSub.class);
ResolvedTypeWithMembers resolvedTypeWithMembers = memberResolver.resolve(resolvedType, null, null);
ResolvedMethod resolvedGetMethod = resolvedTypeWithMembers.getMemberMethods()[0];
System.out.println(resolvedGetMethod.getReturnType()); // TestGenericsImpl
感谢Java类型的擦除(https://docs.oracle.com/javase/tutorial/java/generics/genTypes.html),这很难。我建议将类保存为一个属性,然后如果您绝对必须知道T.的运行时类型,则提供一个getter
public class MyGenericClass<T> {
private final Class<T> type;
public MyGenericClass(Class<T> type) {
this.type = type;
}
public Class<T> getMyType() {
return this.type;
}
}
否则,您可以尝试以下操作:
(Class<T extends TestGenericsInterface>) ((TestGenerics) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
在代码方面,我更喜欢前者的解决方案而不是后者。