首页 > 解决方案 > 为什么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);
}

标签: javalistgenericscasting

解决方案


Java 编译器没有检查您添加到列表中的元素类型,因为您声明了原始类型:

List list = new ArrayList();

然后在执行期间您尝试分配Stringint,这在运行时导致ClassCastException

你在这条线上没有例外int int0 = list.get(0);,因为自动装箱(在这种情况下是取消装箱)。

正是这类问题导致将泛型引入Java 语言。因此,为了让编译器检查放入列表的类型,您需要将声明更改为:

List<Integer> list = new ArrayList<>();

这将告诉编译器检查添加到列表中的值的类型并将它们强制为Integers。因此,基本上运行时错误将被消除并被编译时错误所取代。


推荐阅读