List<? extends Number> arr = Arrays.asList(1,2,3.1f,4.1d);
问题在于,list 变量并没有准确的类型,初始化的参数的类型也是不确定的,这样的不明确的代码为什么可以通过编译。
List<? extends Number> arr = Arrays.asList(1,2,3.1f,4.1d);
问题在于,list 变量并没有准确的类型,初始化的参数的类型也是不确定的,这样的不明确的代码为什么可以通过编译。
|
1
编译器猜的
|
|
JoooooooooMar 25, 2021
2
不都是 Number 吗?
List 可以装 Number. |
|
faust24601Mar 25, 2021 via iPhone
3
范型协变
|
|
xx6412223Mar 25, 2021
4
泛型检查,泛型擦除
|
|
xuanbgMar 25, 2021
5
extends Number,就是当作 Number 类型处理啊
|
|
CodeCodeStudyMar 25, 2021
6
List 里面装的是 Number,1,2,3.1f,4.1d 这些都是 Number
|
|
7
@CodeCodeStudy @xuanbg @Jooooooooo 这个 `list` 既然装的都是 `Number` 那为什么不允许再插入一个 `Number` 进去, `list.add(Integer.valueOf(1))` 将无法通过编译
|
|
hello2060Mar 25, 2021 via iPhone
10
实际类型就是 Number 啊,所以这语句没问题。
|
|
X26U68jE5Q6D0ih0Mar 25, 2021
11
返回的是 Arrays 的内部类 ArrayList, 所以不能 add,remove,clear
|
|
12
@Chengx 首先产生的是编译期错误 `Required type: capture of ? extends Number,Provided: Integer`,而非运行时错误,你说的是运行时错误,再另说。
|
|
13
@Chengx @wunaidouzi
```java List<Number> arr = Arrays.asList(1,2,3.1f,4.1d); arr.add(Integer.valueOf(1)); ``` 不会有编译器错误,只是在运行时候才会出现 `UnsupportedOperationException` 异常 |
|
16
@xuanbg 那我换个表达:
```java List<? extends Number> arr = new ArrayList<Number>(){{ add(1); }}; arr.add(1); //Required type: capture of ? extends Number,Provided: int ``` 这个 ArrayList 可以增减吧,但是第二句依然无法通过编译。 |
|
kuko126Mar 25, 2021
17
List<? super Number> arr = Arrays.asList(1,2,3.1f,4.1d);
arr.add(Integer.valueOf(1)); 不会编译错误 |
|
misdakeMar 25, 2021
21
学一下“协变”
|
|
kuko126Mar 25, 2021
22
|
|
xuanbgMar 25, 2021
23
@szuwl 'add(capture<? extends java.lang.Number>)' in 'java.util.List' cannot be applied to '(int)'
|
|
richardxxxMar 25, 2021 via Android
24
extends 能取不能存
super 能存不能取 |
|
CodeCodeStudyMar 25, 2021
25
改成 ArrayList<? super Number> arr 就可以了
|
|
AoEiuV020Mar 25, 2021
26
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)); 理解一下这两个的区别, |
|
AoEiuV020Mar 25, 2021
27
搞错,是 extends 和 super 的区别,看来我也不熟,
|
|
zm8m93Q1e5otOC69Mar 25, 2021
28
1 不是包装类的子类吧,默认是 int 类型
@szuwl |
|
zm8m93Q1e5otOC69Mar 25, 2021
29
@beichenhpy 我理解错了,应该是 super 。。
|
|
zm8m93Q1e5otOC69Mar 25, 2021
30
逆变不能 get 吗?
List<? super Integer> listSuper = new ArrayList<Number>(); listSuper.add(1); System.out.println(listSuper.get(0)); 我试了一下编译通过了,也没有错误啊。。 |
|
ChengxMar 26, 2021
31
@richardxxx 点睛之笔
|
|
geminius2333Mar 26, 2021
32
Array.asList 方法返回的是 Arrays 的内部类。你要 add 可以 new ArrayList(Arrays.asList(...));
|
|
no1xsyzyMar 26, 2021
33
@beichenhpy 你不能 Integer x = listSuper.get(0)
println 允许的范围大得多罢了,super 仍然潜在蕴含了 extends Object |
|
BronyaMar 26, 2021
34
本人拙见:
初始化的时候已经确定了值都是 Number,因此允许初始化。 但是添加的时候,`List<? extend Number>`并不知道到引用的哪一个子类,规定上界之后`List<? extend Number> = List<Integer> 和 List<? extend Number> = List<Double>`都是成立的,如果可以添加的话会造成`List<Integer>中添加了 Double 类型`,类似这样的代码: ``` List<Integer> intList = new ArrayList<>(); List<? extends Number> numList = intList; numList.add(0.1);//如果允许添加 Integer integer = intList.get(0);//会造成 intList 存储了 Double ``` 因此规定上界(协变?)的时候能取不能存。 super 同理。 |
|
acr0ssMar 26, 2021
35
List<? extends/ super T> 这个也曾困扰我,目前我的理解是。
1. List<? extends/ super T> 而不是 List<T>,目的就是限定只能 add/get 2. ? extends T 这种形式,因为父类无法强转为子类,但子类可以强转为父类;在只有明确上界 T 的 i 情况下,无法 add,只能 get 。 |
|
zhenwangMar 26, 2021
36
|