从Generic创建类对象

时间:2012-11-13 16:42:14

标签: java class generics downcast

在泛型方法中,我似乎无法在运行时访问该方法的泛型类型(错误:无法从类型变量中选择)。

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,但是你可以在这里插入的唯一有效类是你的返回类型。但至少现在它是类型安全的。

完全不方便......

2 个答案:

答案 0 :(得分:4)

与您的断言相反,A的类型在运行时期间已知。有关详细信息,请查看有关type erasure的文档。

简而言之,运行时知道您有一个Whatever类型的对象。但是,如果没有明确提供信息,则无法区分Whatever<A>Whatever<B>。这就是为什么它建议你提供一个类对象。请注意,这与编译阶段不同,在编译阶段已知完整的类型信息。

答案 1 :(得分:1)

无法在运行时选择泛型类型。

请点击此处查看可能的解决方案:Access generic type parameter at runtime?