0

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

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

完全不方便...

4

2 回答 2

4

与您的断言相反, A 的类型在运行时是未知的查看有关类型擦除的文档以获取更多详细信息。

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

于 2012-11-13T16:44:12.373 回答
1

It is not possible to select the generic type at runtime.

See here for a possible solution: Access generic type parameter at runtime?

于 2012-11-13T16:45:43.083 回答