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