无法使用通配符调用泛型方法

3

我有一个如下所示的类定义:

public class Test {
    static <T> List<Class<T>> filter(List<Class<T>> input) {
        // code here
    }

    public static void main(String[] args) {
        List<Class<? extends Throwable>> list =
            new ArrayList<Class<? extends Throwable>>();
        filter(list);
    }
}
filter方法调用会出现以下编译错误:
The method filter(List<Class<T>>) in the type Test is not applicable for the
arguments (List<Class<? extends Throwable>>)

我不明白为什么<T>不能绑定到<? extends Throwable>。有没有泛型专家可以帮助我?

3个回答

4
啊,泛型签名的乐趣。
您可以通过将参数声明为以下内容来修复它:
static <T> List<Class<T>> filter(List<Class<? extends T>> input) {
    // code here
}

至于为什么,我不确定。太多的泛型编译问题都是通过尝试各种方法直到红线消失来解决的。这并不令人满意。


1
也许值得查看http://www.angelikalanger.com/GenericsFAQ/JavaGenericsFAQ.html - akarnokd
这修复了调用方法时的错误(虽然我不明白为什么),但现在方法内部出现了一个错误。基本上,我有一个List<Class<T>>来保存结果,但我无法添加条目,因为Class<? extends T>无法转换为Class<T>。至少这一点对我来说是有意义的。我也将方法更改为返回List<Class<? extends T>>,并且它可以编译。虽然很奇怪,但它确实有效。 - Adam Crume
O'Reilly出版社的《Java泛型与集合》一书(http://oreilly.com/catalog/9780596527754/)也是一个很好的投资,如果你想了解泛型的工作原理。 - skaffman

4
我认为这里的问题在于没有适当的类型可以使用 ?。考虑一下,如果我们为了简单起见,用 AtomicReference 替换 Class
static <T> void filter(List<AtomicReference<T>> input) {
    T value = input.get(0).get();
    input.get(1).set(value);
}

如果input包含一个AtomicReference<Integer>和一个AtomicReference<String>,我们会遇到麻烦。
指向指针的底层问题在多态存在的情况下很难解决。没有泛型我们可以草率地处理。有了泛型,我们需要确切地表达某些意思。

不错的例子。开始有点明白了。 - Adam Crume
1
最后一行应该是 input.get(1).set(value) - JHH

0

你也可以像下面这样编写主函数:

public static void main(String[] args) {
    List<Class<Throwable>> list =
        new ArrayList<Class<Throwable>>();
    filter(list);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接