java - 为什么不能列出 <? extends List<T>> 被分配给 List<List<T>>

标签 java generics

我的类(class)有一个属性是某个类(class)的二维列表T .

将此属性创建为 List<? extends List<T>> 似乎是合乎逻辑的, 从而允许它被分配 List<ArrayList<T>>List<LinkedList<T>除了List<List<T>> .

我的 getter 将返回 List<List<T>> 似乎也是合乎逻辑的,因为我们不需要告诉消费者这个列表可以分配什么,因为消费者会将他从 getter 获得的对象分配给变量,而不是相反。

但是,我的 getter 拒绝自动转换 List<? extends List<T>>List<List<T>> ,抛出 IncompatibleType 错误。为什么不能强制呢?

最佳答案

@JB-Nizet很好地解释了原因:它允许您将 ArrayList 添加到 LinkedList -s 的列表中。

简短的回答是,当然,你不能那样做,因为编译器不会让你那样做;)

让我再举一个例子。您基本上不能向此类集合添加任何内容:

List<? extends List<T>> list = new ArrayList<>();
list.add(new LinkedList<T>()); // compile error
list.add(new ArrayList<T>()); // compile error
List<T> sublist = new ArrayList<>();
list.add(sublist); // compile error

如果这是你想要的,那么你可以在你的 getter 中使用任何列表类型并返回通配符类型:

public List<? extends List<T>> getSomething() {
    List<ArrayList<T>> list = new ArrayList<>();
    // do something
    return list; // List<ArrayList<T>> converts automatically to List<? extends List<T>
}

如果您希望客户端向该列表添加但不删除内容,那么您可以使用super 关键字:

List<? super ArrayList<T>> list = new ArrayList<>();
list.add(new ArrayList<T>()); // this is fine

另一方面,如果你想允许这两种操作,那么就不要使用通配符:

public List<List<T>> getSomething() {
    return new ArrayList<>();'
}

关于java - 为什么不能列出 <? extends List<T>> 被分配给 List<List<T>>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43199488/

相关文章:

Java 泛型和注解 : Type-Safe

java - 在Java中,object.class有什么作用?

java - 何时记录链式异常?

java - 将 HashMap 值添加到 TreeSet 时出错

java - Android PHP 向 MySQL 发出请求

java - 如何从 Java 中的 url 获取 JSON 数据?

java - 具有继承和泛型的流畅 API

java - 如何限制自引用类型?

java.lang.IllegalArgumentException : json string can not be null or empty

java.lang.NullPointerException