为什么将List<String>赋值给List<Integer>可以用get方法取出,反之则抛出ClassCastException?

问题遇到的现象和发生背景

将List赋值给List可以用get方法取出,反之则抛出ClassCastException

问题相关代码,请勿粘贴截图
public class ErasureTest {
    public static void main(String[] args) {
        List<String> ls = new ArrayList<>();
        ls.add("Hello Java");
        List l = ls;
        List<Integer>li = l;
        System.out.println(li.get(0));

//        List<Integer> li = new ArrayList<>();
//        li.add(6);
//        li.add(9);
//        List list = li;
//        // 下面代码引起“未经检查的转换”的警告,编译、运行时完全正常
//        List<String> ls = list;     ////        // 但只要访问ls里的元素,如下面代码将引起运行时异常。
//        System.out.println(ls.get(0));
    }
}

首先说,这个不是编译的问题,如果换成如下写法,编译代码就不会省略,但结果还是一样的:

img

这个主要原因在于泛型的类型擦除,任何泛型(如果不设置上限)在编译之后的JVM中都被擦除了,比如List<Integer>在运行时,虚拟机中的代码其实是List<Object>

详情可以参考一下这篇文章:https://blog.csdn.net/qq_34972627/article/details/122198674

原始类型可以存取任意类型的值,对于泛型类型,只能存取泛型参数指定类型的值。

img


这是复制你这代码编译后的class文件,编译的时候把你写的代码是进行了优化的;
报错不是因为获取数据的时候报错,而是输出的时候才会报错,
前一个不报错,是因为get到的是String类型,不存在强制转换类型,调用输出打印方法没有问题

后一个会报错,因为本身是Integer类型,输出时强转为String就报错了

img

类型不对。
li是Integer类型的,你赋值给了String类型的集合。