报告的通用类型不正确 - 为什么?

时间:2010-08-31 15:58:56

标签: java generics

为什么这不起作用?

public class FooImpl implements Foo { /* ... */ }

public class Main {
    public static <T> Collection<T> getList(Class<? extends T> itemClass) { /* ... */ }

    public static void main(String[] args) {
        Collection<Foo> foos = getList(FooImpl.class);
    }
}

在声明foos的行上,我收到“Incompatible types. Required: Collection<Foo>, found: Collection<FooImpl>”错误。知道为什么吗?

4 个答案:

答案 0 :(得分:4)

试试这个:

Collection<Foo> foos = Main.<Foo>getList(FooImpl.class);

当你创建getList()方法时,它会说它将被输入T.并且它还说它需要一个子类型为T的参数(一个T类的子类型是精确的)

由于你从未指定过什么,getList会认为它是FooImpl所以getList()会返回FooImpl的集合。

根据我给你的解决方案,你指定T是Foo,所以参数需要是Foo的子类型。例如FooImpl


资源:

答案 1 :(得分:3)

因为它返回了FooImpl的集合,而您希望它返回其超类型的集合。您需要更明确地定义:

public class FooImpl implements Foo { /* ... */ }

public class Main {
    public static <S, T extends S> Collection<S> getList(Class<T> itemClass) { /* ... */ }

    public static void main(String[] args) {
        Collection<Foo> foos = getList(FooImpl.class);
    }
}

更新:我不得不提到有一个与此相关的JLS / javac错误导致它在使用“普通香草”javac时无法编译。另请参阅javac bug 6369605JLS bug 6369608和此related question。然而,它在Eclipe中工作正常。

如果你坚持在Eclipse上使用javac,那么你最安全的赌注是在Java人员修复它之前确实是手动强制方法调用中的返回类型,如Colin Hebert所示。

答案 2 :(得分:1)

getList返回类型更改为Collection<? extends T>

FooImpl是Foo的实例

但是

Collection<FooImpl> NOT Collection<Foo>

的实例

答案 3 :(得分:0)

我同意BaluC的回答。

只是为了对泛型检查部分The "extends" Wildcard Boundary

“extends”的基本理解
  

使用带有鞋面的通配符时   限制写入是不安全的   名单。毕竟,汽车永远是一个   车辆,但车辆并不总是一个   车。