当我投来E[]
(类参数),它需要我补充爪哇 - 铸造到E []
@SuppressWarnings("unchecked")
例如:
E[] anArray = (E[]) new Object[10];
我应该做不同的东西,还是应该是这样?
感谢
当我投来E[]
(类参数),它需要我补充爪哇 - 铸造到E []
@SuppressWarnings("unchecked")
例如:
E[] anArray = (E[]) new Object[10];
我应该做不同的东西,还是应该是这样?
感谢
这是正确的。想象一下:
Object[] o = new Object[10];
o[0] = new A(); // A is not a subclass of E
E[] e = o; // Now you have broken the type system: e[0] references something that is not an E.
它的工作方式,你必须显式强制转换,以便让编译器忽略这种可能性。
它应该做的事情,因为那type erasure。
为了避免以抑制警告,你能做的唯一的事情就是用List<E>
(或类似Collection
)。
是的,你应该做的是这样,因为我们不能初始化泛型的数组是这样的:
E[] array = new E[10]; // Compile error
你真的这样做,你写的。我无法知道。
另一种方法是使用对象数组(而不是E)。你可以看到,在Java API开发人员做的也是这样的ArrayList类中:
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer.
*/
private transient Object[] elementData;
,他们根本初始化数组是这样的:
elementData = new Object[size];
而且无处不在,他们使用它,他们投的阵列内容:
/**
* Returns the element at the specified position in this list.
*
* @param index index of the element to return
* @return the element at the specified position in this list
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E get(int index) {
RangeCheck(index);
return (E) elementData[index];
}
我真的不知道,但我认为第一种方法更快,因为在运行时不需要铸造。我想,Java VM会花费一些时间来铸造它。我为什么这么想?正因为如此,在运行时提供了一个错误:
Integer i = new Integer(34);
Object o = i;
String s = (String) o; // Runtime error
因此,这意味着虚拟机真正检验它是否是一个字符串。但事实上,编译器类型擦除让我觉得它没有任何区别。有人可以澄清吗?
*声明一个泛型类型的数组不是问题。 'E []数组;'完全没问题。 –
@ TomHawtin-tackline:好的,我明白了,我将编辑:D –
运行时迟早会执行一个运行时类,并在适当的时候抛出ClassCastException。这不是C/C++世界及其未定义的行为。 – gpeche
您应该阅读Effective Java书。总之,不可能确切知道你的正确行为方式是因为我们不知道你在做什么,但通常你不应该压制这个警告。所以最有可能的解决方案是使用类型安全的泛型集合而不是数组。
使用'ArrayList'作为例子,它抑制了这个警告,那么在数组上使用'ArrayList'会怎样? – Stripies
看@gpeche说什么。数组不是类型安全的。这只是泛型的工作方式 - 编译器不能确保你正确地处理它们。当使用泛型ArrayList <>(而不是未经检查的ArrayList!)时,您将停留在泛型类型的擦除世界中,编译器仍然可以跟踪所有类型。 –
但'ArrayList <>'也使用不安全的方法。下面是从'的ArrayList <>' @SuppressWarnings( “未登记”) ÈelementData中(INT指数){ 返回(E)elementData中[索引]的方法; } – Stripies
@Mehrdad为什么要使用C#? – Stripies
哈哈这是一个笑话,旨在解决这个问题(因为'新T []'完全可以在C#中)...并不意味着你认真对待它。:) – Mehrdad
@Mehrdad我想通了,但我不喜欢C#,因为只能在Windows上使用它,但那不是重点。 – Stripies