[英]Is List<Double> a subtype of List<? extends Number> and why?
[英]Logically,double sumOfList(List<? extends Double> list) will make the function become read-only mode , why list.remove() can be compiled successfully
邏輯上, static double sumOfList(List<? extends Double> list)
會使函數變成只讀模式,那為什么list.remove()
可以編譯成功
public class Extend_char {
public static void main(String[] args) {
{
List<Double> list = new ArrayList<>();
list.add(1.2);
list.add(2.2);
list.add(3.2);
System.out.println(sumOfList(list));
System.out.println(list);
}
static double sumOfList(List<? extends Double> list) {
double sum = 0;
for (int i=0; i<list.size(); i++) {
double n = list.get(i);
sum = sum + n;
}
//list.add(new Double(5.5)); Cannot compile and call normally
list.remove(2.2); //Can compile and call normally
return sum;
}
}
邏輯上,static double sumOfList(List<? extends Double> list) 會使函數變成只讀模式
看,這就是編程的問題。 這太復雜了——所以我們提供了過於簡單的解釋。
你一直是這件事的受害者。 List<? extends Double>
List<? extends Double>
不是“只讀列表”。
但是我可以看到試圖提供幫助的人是如何告訴你的。
看, List<? extends Something>
List<? extends Something>
是,它可以讓你提供一個List<Something>
,或List<SomeChildOfSomething>
如果可以在這樣的事情上調用.add(instanceOfSomething)
,那就是問題。
想象一下這個方法:
void foo(List<? extends Number> list) {
list.add(5); // an integer
}
List<Double> listOfDoubles = new ArrayList<Double>();
foo(listOfDoubles);
listOfDoubles.get(0); // oh dear. Now what?
看到問題了嗎? 一個解決方案是確保所有會失敗的方法,除非他們知道確切的類型,否則是不允許的。 add
就是這樣一種方法。 出於顯而易見的原因, addAll
和set
也是addAll
。 你不能調用那些,除非你知道列表是你傳遞給這些方法的表達式的確切類型,或者它的超類型(這就是為什么你可以在List<? super Double>
上調用.add
正好)。
但是修改列表的方法不會導致此類問題 - 基本上所有不采用 T 類型元素(集合)的方法,例如.clear()
、 .remove()
、 removeIf
等?
那些就好了。
TL;DR: List<? extends AThingie>
List<? extends AThingie>
不是“只讀列表”。 那是完全錯誤的。 不過,這是一個可以理解但過於簡單化的解釋。 不要對誰告訴你這些太苛刻。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.