简体   繁体   English

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

[英]Unchecked or Unsafe Operation error with Array of ArrayLists

When I declare the Array of ArrayLists below, it compiles correctly but has a warning stating, "Unchecked or Unsafe operations." 当我在下面声明ArrayLists的Array时,它可以正确编译,但是有一个警告,指出“未检查或不安全的操作”。 Node is an inner class that I created within my public class. Node是我在公共类中创建的内部类。

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

I already tried both of the following, neither of which compiled: 我已经尝试了以下两种方法,但都没有编译:

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

What is the issue here? 这是什么问题? Thank you for any help. 感谢您的任何帮助。

Generic types are non-refied. 泛型类型是未定义的。 That is they are fictitious and not available at run time. 也就是说,它们是虚拟的,在运行时不可用。 For an instance ArrayList<String> becomes ArrayList at run time. 对于实例, ArrayList<String>在运行时变为ArrayList All the generic information is erased at the time you compile the code. 编译代码时,所有通用信息都将被删除。

On the other hand arrays are refied, meaning they have more information retained at run time. 另一方面,数组被保留,这意味着它们在运行时保留了更多信息。 So in run time all you have is new ArrayList[5] . 因此,在运行时,您只有new ArrayList[5] That's why compiler does not allow this. 这就是为什么编译器不允许这样做。

These operations are illegal because they are not type safe. 这些操作是非法的,因为它们类型不安全。

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

If it were legal, casts generated by the compiler could fail at runtime. 如果合法,则编译器生成的强制转换可能会在运行时失败。 This will violate the fundamental guarantee provided by the generic type system. 这将违反通用类型系统提供的基本保证。

Arrays know their component type at runtime and every time you set a non-null reference on an array, it checks at runtime, that the object the reference points to is an instance of the array's component type; 数组在运行时知道它们的组件类型,并且每次在数组上设置非空引用时,它都会在运行时检查引用所指向的对象是数组组件类型的实例。 if it isn't, it's guaranteed to throw an ArrayStoreException . 如果不是,则保证抛出ArrayStoreException

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

However, it's not possible to check that an object is an instance of a parameterized type, since objects do not know their type arguments at runtime. 但是,由于对象在运行时不知道其类型参数,因此无法检查对象是否为参数化类型的实例。 It's only possible to check that an object is an instance of a reified type at runtime; 在运行时只能检查一个对象是否是某种类型的实例; and that's why array component types are only allowed to be reified types. 这就是为什么只允许将数组组件类型作为类型化的原因。

You can still create an array of the raw type and assign it to the type of array of the parameterized type, as you are doing: 您仍然可以创建原始类型的数组,并将其分配给参数化类型的数组的类型,如下所示:

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

Or you can create an array of the unbounded wildcard type (which is also reified) and then explicitly cast it to the type of array of the parameterized type: 或者,您可以创建一个无界通配符类型的数组(也已对其进行修饰),然后将其显式转换为参数化类型的数组类型:

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

In both cases there will be an unchecked warning. 在这两种情况下,都会出现未经检查的警告。 By giving you a warning, that means you take responsibility for bad things that might happen. 通过警告您,这意味着您应对可能发生的不良事件负责。 For example: 例如:

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>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM