【问题标题】:Incorrect generic type reported -- why?报告了不正确的泛型类型——为什么?
【发布时间】:2010-08-31 15:58:55
【问题描述】:

为什么这不起作用?

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&lt;Foo&gt;, found: Collection&lt;FooImpl&gt;”错误。知道为什么吗?

【问题讨论】:

    标签: java generics


    【解决方案1】:

    试试这个:

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

    当您创建getList() 方法时,它说它将使用 T 进行类型化。它还说它需要 T 的子类型(准确地说是 T 的子类型的类)的参数。

    由于您从未指定 T 是什么,因此 getList 假设它将是 FooImpl,因此 getList() 返回一个 FooImpl 的集合。

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


    资源:

    【讨论】:

    • 接受这个答案,因为这是在 javac 中工作的唯一解决方案。更优雅的解决方案,参考下面BalusC的回答
    【解决方案2】:

    因为它返回的是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 错误导致它在使用“plain vanilla”javac 时无法编译。另请参阅javac bug 6369605JLS bug 6369608 和此related question。但是,它在 Eclip 中运行良好。

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

    【讨论】:

      【解决方案3】:

      getList返回类型更改为Collection&lt;? extends T&gt;

      FooImpl 是 Foo 的实例

      但是

      Collection&lt;FooImpl&gt;不是 Collection&lt;Foo&gt; 的实例

      【讨论】:

      • 什么都没有改变。尽管如此,JVM 还是选择了最具体的类来分配给通配符
      【解决方案4】:

      我同意 BaluC 的回答。

      只是为了基本了解泛型检查部分The "extends" Wildcard Boundary中的“扩展”@

      当使用带有大写的通配符时 绑定它是不安全的写入 列表。毕竟,汽车总是 车辆,但车辆并不总是 汽车。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-10
        • 2021-12-21
        • 1970-01-01
        • 2021-12-27
        • 1970-01-01
        相关资源
        最近更新 更多