当我在下面声明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];
这是什么问题?谢谢您的帮助。
答案 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>