代码之家  ›  专栏  ›  技术社区  ›  Sergey Mikhanov

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

  •  2
  • Sergey Mikhanov  · 技术社区  · 14 年前

    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 回复  |  直到 14 年前
        1
  •  4
  •   Colin Hebert    14 年前

    试试这个:

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

    getList() 方法,它说它将被类型化为T。它还说它将需要一个T的子类型的参数(确切地说是T的子类型的一类)。

    由于您从未指定什么将不会是,所以getList假设它将是 FooImpl 所以 获取列表() 返回 FooImpl公司 .

    Foo ,因此参数必须是的子类型 . FooImpl公司 例如。


    资源:

        2
  •  3
  •   Community CDub    8 年前

    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 6369605 JLS bug 6369608 还有这个 related question

    如果您坚持在Eclipse上使用javac,那么在Java人员将其修复之前,最安全的方法就是手动强制方法调用中的返回类型,如colinhebert所示。

        3
  •  1
  •   mhshams    14 年前

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

    FooImpl是Foo的实例

    但是

    Collection<FooImpl> 实例 Collection<Foo>

        4
  •  0
  •   YoK    14 年前

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

    将通配符与大写字母一起使用时 写信给银行是不安全的 车辆,但车辆并不总是