Javagenerics和数组

当我针对unit testing运行时,下面的代码片段仍然有意义。我在标有“>>>>”的行上得到一个ClassCastException(Object不能转换为String)。 这种类型的操作可以在通用中完成吗?

public class ArrayUtils { public static  E[] appendToArray(E[] array, E item) { E[] result = (E[])new Object[array.length+1]; for(int i=0; i >>> String[] appendToArray = ArrayUtils.appendToArray(array, "b"); assertSame("Array is not correct length.", 2, appendToArray.length ); } 

您不应该使用新的Object []创建数组。 您应该使用Array.newInstance(Class clazz, int length)

你正在将ObjectString ,IOW,一个inheritance的类的超类。 它总是被禁止的。 正如AlexR建议的那样,使用Arrays.newInstance() 。 但在这种情况下,你必须传递一个对象的类,如下所示:

 ArrayUtils.append(array, "b", String.class); 

我建议你不要尝试实现动态扩展数组的这种标准行为:它已经在ArrayList类中实现了。 您可以查看源代码以了解它如何处理generics。

我不知道这个代码是什么,但它给垃圾收集器带来了负担,因为要添加一个元素,你需要分配一个新的数组。 您应该使用List任何实现,例如, ArrayList

遗憾的是,无法在Java中动态创建generics类型的数组,因为与generics类型( E )相关的信息不会在运行时传送,因此无法知道要创建的数组类型。

为了解决这个问题,我建议使用与集合库中使用的解决方案类似的解决方案

 T[] java.util.List.toArray(T[] array) 

方法。 也就是说,不是在appendToArray函数中创建一个新数组,而是从外部传递它。 那是:

 public static  E[] appendToArray(E[] array, E item, E[] newArray) { ... your code ... } @Test public void test(){ appendToArray(array, "b", new String[array.length+1]); } 

我知道这看起来不像其他解决方案那么好,但是它的类型安全,并且具有更好的性能,因为它不依赖于reflection。 出于这个原因,建议您使用

 T[] java.util.List.toArray(T[] array) 

它的reflection等效方法

 T[] java.util.List.toArray() 

正如其他人所说,您应该使用Array.newInstance()来创建正确类型的数组的实例。 更有用的是,您可以从原始数组的类中获取所需的组件类型。

此外,我使用System.arraycopy()简化了复制。

 public static  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[] appendToArray(E[] array, E item) { E[] result = java.util.Arrays.copyOf(array, array.length+1); result[result.length-1] = item; return result; }