为什么一个<Integer>的ArrayList加了一个字符串变量就编译成功了?

Why does an <Integer> ArrayList add a string variable and compile successfully?

我很疑惑为什么Integer类型的Arraylist可以加一个String。如下所示,在 addtolist(List list) 方法中,“("0067")" 被添加到列表中,因为它是一个字符串,所以代码应该抛出错误,但实际上并没有。谁能解释为什么这段代码运行成功?

//test program    


import java.util.ArrayList;
import java.util.List;

public class listing {


public static void main(String[] args) {
    List<Integer> lst = new ArrayList<Integer>();

    addToList(lst);

    System.out.println(lst.get(0));
}

public static void addToList(List list) {
    list.add("0067");
}
}

查看方法签名:

public static void addToList(List list)

listraw type,启用警告应该会警告您:

List is a raw type. References to generic type List should be parameterized

要在编译时进行更强的类型检查,您需要将其更改为:

public static void addToList(List<Integer> list)

addToList()中列表的参数类型不是通用的。这意味着在该方法中,您可以将任何对象添加到该列表而不会产生编译器错误,因为只检查参数的通用类型,而不检查传递的列表之一。

为什么这段代码在 运行 时也有效?编译时通用类型信息被擦除。所以基本上每个列表在 运行 时都是 List<Object>。如果您在牢记这一点的同时再次查看您的代码,您会发现它是有效的。也因为有a println which takes Object as parameter.

如果您添加

可以编译但不能 运行 的示例
Integer foo = lst.get(0);

在你的代码中

public static void addToList(List list) 

您没有收到编译器警告,因为参数 list 不是通用的。这意味着它等同于 List<Object> list。第一次尝试将元素插入列表时,您会在运行时遇到错误。

只需更改为

public static void addToList(List<Integer> list)

你会得到一个编译时错误。