这不是一个如何做事的问题。这是一个为什么会是这样的问题。
Java 中的数组在运行时知道它们的组件类型,并且由于类型删除,我们不能拥有泛型类型变量的数组对象。允许涉及泛型的数组类型并检查健全的读/写,唯一的问题似乎是分配器表达式。
请注意,Java 编译器还不允许以下操作:
Pong<Integer> lotsofpong [] = new Pong<Integer>[100];
...哪里Pong
只是任何旧的参数类。这里没有什么是未知的。是的,在运行时,lotsofpong
只是一个 Pong
的数组,但我看不出编译器无法记住用于编译时目的的类型参数的原因。好吧,它实际上确实记住了它,因为这些类型在编译时存在,所以唯一的问题似乎是拒绝在编译时为分配器提供特定的涉及泛型参数的组件类型。
即使Pong
的参数是一个泛型类型变量,也不应该产生影响。动态数组仍然是 Pong
的数组,要求每个元素的大小为 Pong
,它不依赖于其类型参数。
是的,我知道有办法解决它 - 要么使用非参数类型的强制转换(可能使用 SuppressWarning),要么使用子类 Pong<Integer>
与非参数类并使用该类型。但是有没有理由不允许这种分配器呢?
最佳答案
基于 Zeller 提供的链接(基于 Josh Bloch - 'Effective Java Book')。
数组不安全,因为以下代码将编译:
String strings [] = {"Foo"};
Object objects [] = strings;
objects[0] = 1;
您将在运行时遇到特殊异常:java.lang.ArrayStoreException。 Java 运行时会在运行时检查您是否将适当的类型放入数组中。
将数组分配给其父类(super class)型的数组称为“协方差”。
保证泛型在编译时是安全的。
如果您在问题中提到的代码片段能够编译,则以下代码也将编译:
Pong<Integer> integerPongs [] = new Pong<Integer>[100];
Object objectPongs [] = integerPongs;
objectPongs[0] = new Pong<String>();
Pong<Integer> stringPong = integerPongs[0]; // ClassCastException
我们的代码变得不安全,因此被规范禁止。
原因:
objectPongs[0] = new Pong<String>();
不会抛出 java.lang.ArrayStoreException 是因为每个 Pong 实例的运行时类型始终是 Pong,因为泛型是一种编译时机制。
关于java 参数类型数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16768386/