Javagenerics和数组初始化

以下是什么解释:

public class GenericsTest { //statement 1 public ArrayList[] lists; public GenericsTest() { //statement 2 lists = new ArrayList[4]; } } 

编译器接受语句1.语句2由编译器标记为“通用数组创建”。

我已经看到关于禁止generics数组的一个很好的解释就是这个 ,认为由于数组是协变的而且generics不是你可以在你允许generics数组的情况下颠覆generics类型。

撇开关于这种语言是否应该极端地在generics的处理中创造这种复杂的不一致性的争论,无论你怎么努力都让你不能自己开枪(如果有人知道关于亲戚的任何好的讨论)问题的优点/缺点请发布,我有兴趣看看论点),如果(2)不是,为什么应该允许声明(1)?

似乎有一些模糊的情况,你可能会无意中导致ClassCastException,如http://java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf (第7.3节)所述

关于这个主题的讨论可以在这里找到http://courses.csail.mit.edu/6.170/old-www/2006-Spring/forum/index.php%3Ftopic=324.msg1131.html

这是因为你无法创建,但你可以使用它们:

 public class GenericsTest { //statement 1 public ArrayList[] lists; public GenericsTest() { //statement 2 lists = new ArrayList[4]; //statement 3 lists[0].add(new Integer(0)); //statement 4 lists[0].add(new String("")); } } 

语句3是可能的,语句4将导致编译器错误。

所以实际的问题是:为什么声明一个通用数组没有错误? ?

在你做错事的那一刻,你总会得到一个错误。 在没有技术问题的情况下添加错误只会增加混乱(尽管编辑可能想要指出这一点)。

在某些情况下,您可能希望使用未经检查的强制转换来略微修改规则。 没有必要强制使用比必要更多的警告抑制来代码(除了指出愚蠢之外)。

在这种情况下,我会避免使用数组。 原始代码中的“列表”声明可以是

 List> lists = new ArrayList>(4); for(int i = 0; i < 4; i++) lists.add(null); // or add an empty ArrayList 

(您应该使用接口而不是变量声明中的实现)

您将使用get()或set()而不是array []语法。 除此之外,它是等价的。