我知道我想要做的事情并不是真的可以用纯java - 只有我看看调试信息才有可能。无论如何我都不会在没有调试的情况下编译,因为我的春天mvc会停止工作。
说,我有以下情况:
一个通用超类:
package com.cinefms.apitester.springmvc.crawlers;
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”是方法“运行”,那么
m.getGenericReturnType();
会返回“T”(没有帮助),而:
m.getReturnType();
给了我“TestGenericsInterface”(也没有帮助)。我一直在看“org.javaruntype”库...但我似乎无法弄明白。
有人可以解释一下吗?谢谢!
答案 0 :(得分:0)
感谢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];
我更倾向于在代码中使用前一种解决方案。
答案 1 :(得分:0)
您可以使用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
答案 2 :(得分:0)
TypeTools是另一种选择:
Class<?> t = TypeResolver.resolveRawArgument(TestGenerics.class, TestGenericsSub.class);
结果如预期:
assert t == TestGenericsImpl.class;