List list1 = new ArrayList(); List<String> list2 = new ArrayList(); List list3 = new ArrayList<String>(); List<String> list4 = new ArrayList<String>();
上面四种新建方法有什么区别
最终低层都会进行类型擦除,本质都一样,只是在使用层上有区别,区分泛型和非泛型而已。
List list1 = new ArrayList(); //可以插入任意类型的数据
List<String> list2 = new ArrayList(); //只能插入String类型的数据
List list3 = new ArrayList<String>(); //可以插入任意类型的数据
List<String> list4 = new ArrayList<String>(); //只能插入String类型的数据
其实这个就是考你对范型的理解。
有了范型,编译器就可以帮助你对类型进行转换。如下:
// 这是你看到的
List<String> list = new ArrayList<>();
String value = list.get(0);
// 实际上的
List list = new ArrayList();
String value = (String) list.get(0);
所以其实楼上的哪位说可以存储任何类型的数据,可以理解为正确,但是也可以说不正确,因为你这里存进去了,但是那边正常取,如果强转失败了是会抛出异常的,你这样只是通过一些 “小聪明” 骗过了编译器的判断而已。
// 这两个实际上是一样的,只是在不同的 IDE 下可能你看的效果不同
// 因为你前面写了 <String> 了,那么后面其实也可以不用写了,编译器已经能判断出来类型了
// 在 IDEA 下是可以省缺后面的 <String> 的,并且它也建议你省缺多余的代码
List<String> list4 = new ArrayList<String>();
List<String> list2 = new ArrayList();
// 这两个的区别就是,是不是使用了范型
// 如果你在之后的代码一直使用的是 List 类型来操作的话,就不会有任何问题
List list1 = new ArrayList();
List list3 = new ArrayList<String>();
// 如果是以下的情况可能就有问题了
List<String> list5 = new ArrayList<>();
List list6 = list5;
list6.add(new Object());
String s = list5.get(0); // 会抛出异常 java.lang.Object cannot be cast to java.lang.String