简体   繁体   English

参数类型的Java数组

[英]java arrays of parametric types

This is not a question how to do things. 不是做事的问题。 It is a question of why is it the way it is. 这是为什么这样的问题。

Arrays in Java know their component type at run time, and because of type erasure we cannot have array objects of generic type variables. Java中的数组在运行时知道其组件类型,并且由于类型擦除,我们无法拥有通用类型变量的数组对象。 Array types involving generics are allowed and checked for sound read/write, the only issue seem to be the allocator expressions. 允许使用涉及泛型的数组类型并检查声音的读/写,唯一的问题似乎是分配器表达式。

Notice that the Java compiler also disallows the following: 请注意,Java编译器还禁止以下操作:

Pong<Integer> lotsofpong [] = new Pong<Integer>[100];

...where Pong is just any old parametric class. ... Pong只是任何旧的参数类。 There is nothing unknown here. 这里没有什么未知的。 Yes, at run-time, lotsofpong would just be an array of Pong , but I cannot see a reason why the compiler cannot remember the type parameter for compile-time purposes. 是的,在运行时, lotsofpong只是Pong的数组,但我看不出编译器无法记住用于编译时目的类型参数的原因。 Well, it actually does remember it, because those types exist at compile time, so the only problem seems to be the refusal to give the allocator at compile-time a particular generic-parameter-involving component type. 好吧,它确实会记住它,因为这些类型在编译时就存在,所以唯一的问题似乎是拒绝在编译时为分配器提供特定的涉及泛型参数的组件类型。

Even if the parameter of Pong was a generic type variable that should not make a difference either. 即使Pong的参数是通用类型变量,也不应有所作为。 The dynamic array would still be an array of Pong , requiring per element the size of a Pong , which does not depend on its type parameter. 动态数组仍将是Pong的数组,每个元素需要Pong的大小,而Pong的大小并不取决于其类型参数。

Yes, I know there are ways around it - either use casts (perhaps with SuppressWarning) from the non-parametric type, or subclass Pong<Integer> with a non-parametric class and use that type instead. 是的,我知道有很多解决方法-使用非参数类型的强制类型转换(也许使用SuppressWarning),或者使用非参数类型的子类Pong<Integer>并改用该类型。 But is there a reason why this kind of allocator is not allowed? 但是,为什么不允许这种分配器有原因吗?

Based on the link that was provided by Zeller (based on Josh Bloch - 'Effective Java Book'). 基于Zeller提供的链接(基于Josh Bloch-“有效Java书籍”)。

Arrays are not safe because the following code will compile: 数组不安全,因为将编译以下代码:

String strings [] = {"Foo"};
Object objects [] = strings;
objects[0] = 1;

You will get a special exception at run-time : java.lang.ArrayStoreException. 您将在运行时收到一个特殊的异常:java.lang.ArrayStoreException。 Java run-time cheks at run-time that you put an appropriate type into the array. 您将适当的类型放入数组时,Java运行时会在运行时进行检查。

Assigning an array to an array of its super type is called 'Covariance'. 将数组分配给其超类型的数组称为“协方差”。

Generics are guaranteed to be safe at compile-time . 泛型在编译时保证是安全的。

If the code snippet that you mentioned in the question was able to be compiled, the following code would also compiles: 如果您在问题中提到的代码片段能够被编译,则下面的代码也会被编译:

Pong<Integer> integerPongs [] = new Pong<Integer>[100];
Object objectPongs [] = integerPongs;
objectPongs[0] = new Pong<String>();
Pong<Integer> stringPong = integerPongs[0]; // ClassCastException

Our code becomes not safe therefore it was forbidden by the specification. 我们的代码变得不安全,因此被规范禁止。

The reason that : 原因如下:

objectPongs[0] = new Pong<String>();

does not throw java.lang.ArrayStoreException is because the run-time type of each instance of Pong is always Pong since Generics is a compile-time mechanism. 不会抛出java.lang.ArrayStoreException的原因是,由于泛型是一种编译时机制,因此Pong的每个实例的运行时类型始终为Pong。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM