ArrayLists数组发生未经检查或不安全的操作错误

时间:2018-10-28 23:42:15

标签: java arrays generics arraylist

当我在下面声明ArrayLists的Array时,它可以正确编译,但是有一个警告,指出“未检查或不安全的操作”。 Node是我在公共类中创建的内部类。

private ArrayList<node>[] arr = new ArrayList[5];

我已经尝试了以下两种方法,但都没有编译:

private ArrayList<node>[] arr = new ArrayList<node>[5]; 
private ArrayList<node>[] arr = new ArrayList<>[5];

这是什么问题?谢谢您的帮助。

2 个答案:

答案 0 :(得分:0)

通用类型是未定义的。也就是说,它们是虚拟的,在运行时不可用。对于实例,ArrayList<String>在运行时变为ArrayList。编译代码时,所有通用信息都会被删除。

另一方面,对数组进行修正,这意味着它们在运行时保留了更多信息。因此,在运行时,您只有new ArrayList[5]。这就是为什么编译器不允许这样做。

这些操作是非法的,因为它们类型不安全。

private ArrayList<node>[] arr = new ArrayList<node>[5]; 
private ArrayList<node>[] arr = new ArrayList<>[5];

如果合法,则编译器生成的强制转换可能会在运行时失败。这将违反通用类型系统提供的基本保证。

答案 1 :(得分:0)

数组在运行时知道它们的组件类型,并且每次在数组上设置非空引用时,它都会在运行时检查引用所指向的对象是否是数组组件类型的实例。如果不是,则可以保证抛出ArrayStoreException

Object[] foo = new Integer[42];
foo[0] = "bar"; // throws ArrayStoreException -- "bar" is not an instance of Integer

但是,由于对象在运行时不知道其类型参数,因此无法检查对象是否为参数化类型的实例。在运行时只能检查对象是否为修饰类型的实例。这就是为什么只允许将数组组件类型作为化类型。

您仍然可以创建原始类型的数组,并将其分配给参数化类型的数组的类型,就像这样做:

private ArrayList<node>[] arr = new ArrayList[5];

或者您可以创建一个无界通配符类型的数组(也可以进行修正),然后将其显式转换为参数化类型的数组类型:

private ArrayList<node>[] arr = (ArrayList<node>[])new ArrayList<?>[5];

在两种情况下,都会出现未经检查的警告。通过警告您,这意味着您应对可能发生的不良事件负责。例如:

Object[] foo = arr;
foo[0] = new ArrayList<String>(); // no ArrayStoreException -- it is an instance of ArrayList
// now you have an ArrayList<node>[] that contains an ArrayList<String>
相关问题