List extends Numbe抗投诉服务器r> arr = Arrays.asList(1,2,3.1f,4.1d);
问题在于,list 变量并没有准确的类型,初始化的参数的类型也是不确定的,这样的不明确的代码为什么可以通过编译。
编译器猜的
不都是 Number 吗?
List 可以装 Number.
范型协变
泛型检查,泛型擦除
extends Number,就是当作 Number 类型处理啊
List 里面装的是 Number,1,2,3.1f,4.1d 这些都是 Number
这个 `list` 既然装的都是 `Number` 那为什么不允许再插入一个 `Number` 进去, `list.add(Integer.valueOf(1))` 将无法通过编译
Arrays.asList 不可修改
Arrays.asList 返回长度固定的 List
支持 set 修改元素值
不支持 add, remove, clear
实际类型就是 Number 啊,所以这语句没问题。
返回的是 Arrays 的内部类 ArrayList, 所以不能 add,remove,clear
首先产生的是编译期错误 `Required type: capture of ? extends Number,Provided: Integer`,而非运行时错误,你说的是运行时错误,再另说。
```java
List
arr = Arrays.asList(1,2,3.1f,4.1d);
arr.add(Integer.valueOf(1));
```
不会有编译器错误,只是在运行时候才会出现 `UnsupportedOperationException` 异常
运行时不是 List,而是 Arrays.asList(1,2,3.1f,4.1d)。这个对象不允许增减操作。
允许修改的话类型不安全 你可以参见我这个 ts 的例子。父子类所构成的数组并不是父子关系 https://www.typescriptlang.org/zh/play?#code/MYGwhgzhAECC0G8BQ1XTNAvNAjEgvkqJDAELQCmAHgC4UB2AJjPMmtAEZbQBMBR4KNADClWg2ZxEKNMG59CRAPb0INTgC5opANoBdbvuWr1YLbH3cuAemvRAFzaB4Q0Cb8YBnE9NEAhboDztQKJpgHgVAejNtIyQwHQAGA2x6CgB3EQAKAEokJA5IvQA6Gzs3QA1tQAp1QDvUwAyMzkzoP2DRQEKbQEhzTiQgA
那我换个表达:
```java
List extends Number> arr = new ArrayList(){{ add(1); }};
arr.add(1); //Required type: capture of ? extends Number,Provided: int
```
这个 ArrayList 可以增减吧,但是第二句依然无法通过编译。
List super Number> arr = Arrays.asList(1,2,3.1f,4.1d);
arr.add(Integer.valueOf(1));
不会编译错误
int != Integer
问的是 extends 并非 super
https://blog.csdn.net/Marmara01/article/details/85234908
学一下“协变”
https://docs.oracle.com/javase/tutorial/java/generics/wildcardGuidelines.html
'add(capture extends java.lang.Number>)' in 'java.util.List' cannot be applied to '(int)'
extends 能取不能存
super 能存不能取
改成 ArrayList super Number> arr 就可以了
List extends Number> arr = Arrays.asList(1,2,3.1f,4.1d);
List extends Number> arr = new ArrayList(Arrays.asList(1,2,3.1f,4.1d));
理解一下这两个的区别,
搞错,是 extends 和 super 的区别,看来我也不熟,
1 不是包装类的子类吧,默认是 int 类型
@szuwl
我理解错了,应该是 super 。。
逆变不能 get 吗?
List super Integer> listSuper = new ArrayList();
listSuper.add(1);
System.out.println(listSuper.get(0));
我试了一下编译通过了,也没有错误啊。。
点睛之笔
Array.asList 方法返回的是 Arrays 的内部类。你要 add 可以 new ArrayList(Arrays.asList(...));
你不能 Integer x = listSuper.get(0)
println 允许的范围大得多罢了,super 仍然潜在蕴含了 extends Object
本人拙见:
初始化的时候已经确定了值都是 Number,因此允许初始化。
但是添加的时候,`List extend Number>`并不知道到引用的哪一个子类,规定上界之后`List extend Number> = List 和 List extend Number> = List`都是成立的,如果可以添加的话会造成`List中添加了 Double 类型`,类似这样的代码:
```
List intList = new ArrayList<>();
List extends Number> numList = intList;
numList.add(0.1);//如果允许添加
Integer integer = intList.get(0);//会造成 intList 存储了 Double
```
因此规定上界(协变?)的时候能取不能存。
super 同理。
List extends/ super T> 这个也曾困扰我,目前我的理解是。
1. List extends/ super T> 而不是 List,目的就是限定只能 add/get
2. ? extends T 这种形式,因为父类无法强转为子类,但子类可以强转为父类;在只有明确上界 T 的 i 情况下,无法 add,只能 get 。
[PECS]( https://stackoverflow.com/questions/2723397/what-is-pecs-producer-extends-consumer-super)