我的班级有一个属性,它是某个班级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错误。为什么不能强迫它?
答案 0 :(得分:1)
@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<>();'
}