这些代码与泛型有什么区别

时间:2019-05-15 20:38:55

标签: java generics

我注意到以下两个代码均有效:

private Node<K,V>[] lst=(Node<K,V>[])(new Node[10]);
private Node<K,V>[] lst=new Node[10];

它们之间有什么区别吗?据我了解,NodeNode<K,V>是不同类型的,并且我们无法使用new Node<K,V>[10]创建数组,因此我们需要使用(Node<K,V>[])进行类型转换。那第二个呢?为什么没有类型转换就可以工作?

此外,我注意到上面的代码并不能保证运行时类型的正确性,如以下示例所示:

List<String> al = new ArrayList<>();
al.add("ax");
al.add("bf");
List<Integer>[] list = (List<Integer>[]) new List[]{al};
System.out.println(list[0]); // ["ax", "bf"] printed

所以我的第二个问题是:是否需要将数组和集合与泛型结合起来? private Node[] lst=new Node[10];总是更好的选择吗?(在这里我不能使用List<List<Integer>>,因为我需要一个固定大小的数组)。谢谢!

PS:我了解一些有关运行时JVM擦除泛型的基本知识,我只是不了解上面的代码是如何工作的

1 个答案:

答案 0 :(得分:0)

  

它们之间有什么区别吗?据我了解,NodeNode<K,V>是不同的类型,我们无法使用new Node<K,V>[10]创建数组,因此我们需要使用(Node<K,V>[])进行类型转换。

这实际上不是事实。 Node[]Node<K,V>[]属于同一类型,因为Java在编译时会处理它们。此外,此代码:

private Node<K,V>[] lst=(Node<K,V>[])(new Node[10]);
应避免使用

,因为它包含不必要的代码和不良做法。如果可能,请在实例化时避免类型转换。更好的实例化方式是

private Node<K, V>[] lst = new Node<>[10];

Java理论上应该在右侧推断泛型。

  

是否需要将数组和集合与泛型结合起来?

我真的不明白为什么还要尝试将集合与数组结合起来,但是,将这三个结合起来会使这段代码很难看。

  

是私有节点[] lst =新节点[10];总是一个更好的选择?

取决于上下文。当您已经知道要存储多少个元素时,请选择数组,否则采用集合。

  

此外,我注意到上面的代码不能保证运行时类型的正确性:

List<Integer>[] list = (List<Integer>[]) new List[]{al};

您基本上想在这里做的是创建一个包含多态列表的数组。然后创建一个新列表(不是实例化LinkedList还是ArrayList?),其第一个条目为字符串列表。然后,您尝试对其进行强制转换,但是泛型的工作方式(如前所述)ListList<K>基本相同。这样,在运行时,您将失去类型安全性。尝试避免这种情况。

希望我能帮上忙。