为什么在将任何对象类型更改为泛型后,我仍然可以将任何对象添加到具有原始类型引用类型的列表中?



我声明并初始化了myList,原始引用类型为List,原始对象类型为ArrayList。然后,我将myList重新引用到一个新的通用ArrayList of Longs。我认为在此列表中添加除 Long 以外的任何内容都会导致错误。

List myList = new ArrayList();
myList = new ArrayList<Long>();
myList.add(3.4d);
myList.add(4.0f);
myList.add("weird");
myList.add('w');
System.out.println(myList);

但是,这将运行而不会出现错误或异常。这怎么合法?

如果将其声明为List<Long>,您将获得静态编译时类型检查。执行类型擦除,JVM 在运行时不知道有关这些类型的任何信息。

List<Long> myList = new ArrayList<>();
myList.add("foo");

将给出编译错误,同时:

public void breakGeneric(List list) {
list.add("foo");
}
....
List<Long> myList = new ArrayList<>();
breakGeneric(myList);

将"foo"添加到列表中,无论类型是什么类型。大多数 IDE 会因为丢失泛型类型而感到厌烦。

在新语句中具有该类型new ArrayList<Long>()只有在您链接该语句(即new ArrayList<Long>().add("foo").这是仅在new语句中的泛型类型会导致编译问题的唯一方法。

这怎么合法?

因为 java 编译器只考虑声明的类型,在本例中是原始类型List

List myList

可以容纳任何类型的对象。

赋值myList = new ArrayList<Long>()对声明的myList类型没有影响。

相关内容

最新更新