当我针对单元测试运行时,下面的代码段仍然有意义。我在标有“>>>>”的行上得到一个ClassCastException(Object不能转换为String)。这种类型的操作可以通用吗?
public class ArrayUtils<E> {
public static <E> E[] appendToArray(E[] array, E item) {
E[] result = (E[])new Object[array.length+1];
for(int i=0; i < array.length; i++ ) {
result[i] = array[i];
}
result[result.length-1] = item;
return result;
}
}
@Test
public void testAppendToArray() {
String[] array = new String[1];
array[0] = "a";
assertSame("Array is not correct length.", 1, array.length );
>>>> String[] appendToArray = ArrayUtils.<String>appendToArray(array, "b");
assertSame("Array is not correct length.", 2, appendToArray.length );
}
答案 0 :(得分:5)
您不应该使用新的Object []创建数组。您应该使用Array.newInstance(Class clazz, int length)
代替。
答案 1 :(得分:1)
你将Object
投射到String
,IOW,一个继承的超类。
它总是被禁止的。正如AlexR建议的那样,请使用Arrays.newInstance()
。但在这种情况下,您必须传递一个对象类,如下所示:
ArrayUtils.<String>append(array, "b", String.class);
我建议你不要尝试实现动态扩展数组的这种标准行为:它已经在ArrayList
类中实现了。您可以查看源代码以了解它如何处理泛型。
答案 2 :(得分:0)
我不知道这个代码是什么,但它给垃圾收集器带来了负担,因为要添加一个元素,你需要分配一个新的数组。您应该使用List
的任何实现,例如ArrayList
。
答案 3 :(得分:0)
遗憾的是,无法在Java中动态创建泛型类型的数组,因为与泛型类型(E
)相关的信息不会在运行时传输,因此无法知道什么类型的要创建的数组。
为了解决这个问题,我建议对one used in collections library
采用类似的解决方案T[] java.util.List.toArray(T[] array)
方法。也就是说,不是在appendToArray
函数中创建新数组,而是从外部传递它。那就是:
public static <E> E[] appendToArray(E[] array, E item, E[] newArray) {
... your code ...
}
@Test
public void test(){
appendToArray(array, "b", new String[array.length+1]);
}
我知道这看起来并不像其他解决方案那么好,但它的类型安全,并且具有更好的性能,因为它不会求助于反射。出于这个原因,建议您使用
T[] java.util.List.toArray(T[] array)
方法超过它的反射等价
T[] java.util.List.toArray()
答案 4 :(得分:0)
正如其他人所说,您应该使用Array.newInstance()
来创建正确类型的数组实例。更有用的是,您可以从原始数组的类中获取所需的组件类型。
另外,我使用System.arraycopy()
简化了复制。
public static <E> E[] appendToArray(E[] array, E item) {
E[] result = (E[])java.lang.reflect.Array.newInstance(array.getClass().getComponentType(), array.length+1);
System.arraycopy(array, 0, result, 0, array.length);
result[result.length-1] = item;
return result;
}
在Java 1.6+中,您可以这样做:
public static <E> E[] appendToArray(E[] array, E item) {
E[] result = java.util.Arrays.copyOf(array, array.length+1);
result[result.length-1] = item;
return result;
}