从逻辑上讲,double sumOfList(List<? extends Double> list) 会使函数变成只读模式,为什么list.remove()可以编译成功
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;
}
}
Logically,static double sumOfList(List<? extends Double> list) will make the function become read-only mode
看,这就是编程的问题。它太复杂了 - 所以我们提供过于简单的解释。
你是这件事的受害者。 List<? extends Double>
是 不是 一个 'read only list'。
但我可以看到试图提供帮助的人是如何告诉你的。
看,List<? extends Something>
的意义在于它可以让您提供 List<Something>
或 List<SomeChildOfSomething>
。 IF 然后可以在这样的事情上调用 .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
也是如此。你不能调用那些,除非你知道列表是你传递给那些方法的表达式的确切类型,或者它的超类型(这就是为什么你 can 调用.add
上一个List<? super Double>
就好了)。
但是修改列表的方法 而不是 会导致此类问题 - 基本上所有不采用 T 类型元素(集合)的方法,例如 .clear()
、.remove()
、removeIf
、等等?
这些都很好。
TL;DR:List<? extends AThingie>
不是 'a read only list'。那是完全错误的。这是一个可以理解但过于简单化的解释。不要对谁告诉你的太苛刻了。
逻辑上,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;
}
}
Logically,static double sumOfList(List<? extends Double> list) will make the function become read-only mode
看,这就是编程的问题。它太复杂了 - 所以我们提供过于简单的解释。
你是这件事的受害者。 List<? extends Double>
是 不是 一个 'read only list'。
但我可以看到试图提供帮助的人是如何告诉你的。
看,List<? extends Something>
的意义在于它可以让您提供 List<Something>
或 List<SomeChildOfSomething>
。 IF 然后可以在这样的事情上调用 .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
也是如此。你不能调用那些,除非你知道列表是你传递给那些方法的表达式的确切类型,或者它的超类型(这就是为什么你 can 调用.add
上一个List<? super Double>
就好了)。
但是修改列表的方法 而不是 会导致此类问题 - 基本上所有不采用 T 类型元素(集合)的方法,例如 .clear()
、.remove()
、removeIf
、等等?
这些都很好。
TL;DR:List<? extends AThingie>
不是 'a read only list'。那是完全错误的。这是一个可以理解但过于简单化的解释。不要对谁告诉你的太苛刻了。