ArrayList的向上转型的小问题

题目描述

之前写力扣就用的 List<String> re = new ArrayList<String>();这个语句,也明白说ArrayList向上转型成了List类型,re说一个List类型,不过今天进行写的时候发现了两句话无法run,想求大家看看为什么,谢谢了

相关代码

List<List> re2 = new ArrayList<ArrayList>();
HashMap<String, List> re3 = new HashMap<String, ArrayList>();

你期待的结果是什么?实际看到的错误信息又是什么?

上面两句都显示java: 不兼容的类型:。。。
有点不太明白向上转型是需要什么情况吗,比较困惑,真的不知道为什么会这样,后面我是把List全改成了ArrayList,也能通过,但是真的不知道为什么上面会不兼容。


回答:

这个是 Java 在编译时的类型擦除导致的类型不安全。

Java 的泛型在编译时会全部被擦除,假设你相关代码可以编译通过:

List<List> re2 = new ArrayList<ArrayList>();

Map<String, List> re3 = new HashMap<String, ArrayList>();

// 编译后

List re2 = new ArrayList();

Map re3 = new HashMap();

re2 为例,对于 List<List> 来说,执行 re2.add(new LinkedList<>()) 对于其定义来说是没有问题的且允许的,但实际上 re2 的实现是 ArrayList<ArrayList>,这样就会导致出现类型转换错误,因为 LinkedList 是不可以强转成 ArrayList 的,为了避免发生这种意外情况,Java 在编译阶段直接就不允许这样的用法。


回答:

楼上说得不错,我做点补充。
其实是可以兼容的,只是写法可能不像你的直觉那样。

List<? extends Number> re2 = new ArrayList<Integer>();

这种可以说是向上转型,即设置擦除上边界,可以想象成在擦除的时候擦除为Number,虽然实际并不一定是这样,不过从语法层面来这么理解应该没什么问题。就像普通的向上强转一样,转化后无法在使用本来的一些方法,而只能使用高层方法,所以这个集合不能够在添加具体的子类,因为无法保证泛型的统一。但获取是可以的,因为至少能保证为number.

以上是 ArrayList的向上转型的小问题 的全部内容, 来源链接: utcz.com/p/944366.html

回到顶部