java 参数类型数组

标签 java arrays parametric-polymorphism

不是一个如何做事的问题。这是一个为什么会是这样的问题。

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/

相关文章:

javascript - 条件语句数组循环

haskell - Traversable 和 MonoTraversable 之间有什么东西吗?

scala - 在Scala中,我可以动态指定参数类型的类型参数吗?

java - Spring , hibernate : failed to lazily initialize a collection

java - 在 JBOSS 7.1.1 中排除 EAR 中的模块

javascript - 如何在 JavaScript 中编写一个表达式来调用数组中的函数?

generics - 何时以及为何使用 AsRef<T> 而不是 &T

java - 将列表作为值插入映射中

java - Appium:isDisplayed() 与 findElements(by).size

python - 将 numpy 数组从值转换为索引