在泛型方法中,我似乎无法在运行时访问该方法的泛型类型(错误:无法从类型变量中选择)。
public <A> A get(Animal a) {
Class ac = a.getClass();
if(ac.isAssignableFrom(A.class)) { // <- not working!
return (A) a;
} else {
// error handling
}
}
我这样做的原因是能够安全地降低内容,例如:
Animal a = new Dog();
Dog d = get(a); // <- OK
Cat c = get(a) // <- incompatible types, caught by else block
我发现了一篇来自9年多以前的帖子,问题完全相同: https://forums.oracle.com/forums/thread.jspa?threadID=1184291
在那里,解决这个问题的想法是在构造函数中提供一个Class对象,并使用此变量来检查它是否可分配。这似乎是一个非常愚蠢的解决方案,因为你可以把任何课程放在那里,所有不错的类型检查都没用......
所以,同样的问题:为什么在构造函数中提供<any>.class
,在运行时期间<A>
的类型是完全已知的?如何访问<A>
的实际类型?
找到了一个非常难看的解决方案:
public <A> A get(Animal a, Class<A> clazz) {
// same as above...
}
所以现在你必须提供Class
,但是你可以在这里插入的唯一有效类是你的返回类型。但至少现在它是类型安全的。
完全不方便......
答案 0 :(得分:4)
与您的断言相反,A的类型在运行时期间不已知。有关详细信息,请查看有关type erasure的文档。
简而言之,运行时知道您有一个Whatever
类型的对象。但是,如果没有明确提供信息,则无法区分Whatever<A>
和Whatever<B>
。这就是为什么它建议你提供一个类对象。请注意,这与编译阶段不同,在编译阶段已知完整的类型信息。
答案 1 :(得分:1)
无法在运行时选择泛型类型。
请点击此处查看可能的解决方案:Access generic type parameter at runtime?