java - 为什么java编译器在获取之前不检查列表参数中的对象类型?
问题描述
在需要获取对象之前,Java 编译器似乎并不关心列表中的类型是否匹配:
private static void print(List<Integer> list) { //private static <T> void print(List<T> list) { will also do
for (Object object: list)
System.out.print(object);
int int0 = list.get(0); //ok
//int int1 = list.get(1); //ClassCastException if run
}
public static void main(String[] args) {
List list = new ArrayList();
list.add(1);
list.add("2");
print(list);
}
解决方案
Java 编译器没有检查您添加到列表中的元素类型,因为您声明了原始类型:
List list = new ArrayList();
然后在执行期间您尝试分配String
给int
,这在运行时导致ClassCastException
。
你在这条线上没有例外int int0 = list.get(0);
,因为自动装箱(在这种情况下是取消装箱)。
正是这类问题导致将泛型引入Java 语言。因此,为了让编译器检查放入列表的类型,您需要将声明更改为:
List<Integer> list = new ArrayList<>();
这将告诉编译器检查添加到列表中的值的类型并将它们强制为Integer
s。因此,基本上运行时错误将被消除并被编译时错误所取代。