如何创建新的AnyType []数组?

时间:2010-04-19 00:37:11

标签: java arrays generics

在这种情况下哪种方法最好?我想要一个与原始类型和长度相同的未初始化数组。

public static <AnyType extends Comparable<? super AnyType>> void someFunction(AnyType[] someArray) {

    AnyType[] anotherArray = (AnyType[]) new Comparable[someArray.length];
     ...or...
    AnyType[] anotherArray = (AnyType[]) new Object[someArray.length];

    ...some other code...
}

谢谢, CB

3 个答案:

答案 0 :(得分:7)

AnyType[] anotherArray = (AnyType[])java.lang.reflect.Array.newInstance(
      someArray.getClass().getComponentType(), someArray.length);

答案 1 :(得分:5)

阵列和泛型并不能很好地混合。这是因为数组是covariant而泛型不是。让我举个例子:

public static void main(String args[]) {
  foo(new Float[1]);
}

public static void foo(Number[] n) {
  n[0] = 3;
}

该代码编译但会产生ArrayStoreException

因此,重新创建该数组时的问题是它可能不是AnyType的数组,但它可能是AnyType的子类。您当然可以使用someArray.getClass()并使用反射创建数组。

但总体主题是你应该支持List s而不是数组,因为List没有相同的问题。将代码更改为:

public static void main(String args[]) {
  foo(new ArrayList<Float>());
}

public static void foo(List<Number> list) {
  list.add(3);
}

代码将无法编译,这是一个更好的结果。

答案 2 :(得分:5)

一个很好的参考是看<T> T[] Collection.toArray(T[])

如何实现AbstractCollection
public <T> T[] toArray(T[] a) {
    // Estimate size of array; be prepared to see more or fewer elements
    int size = size();
    T[] r = a.length >= size ? a :
              (T[])java.lang.reflect.Array
              .newInstance(a.getClass().getComponentType(), size);
    //...

所以该技术使用:

如果你绝对必须创建一个“通用”数组,那么这种传递instanceof T[]并使用反射来实例化另一个的技术就是Java Collections Framework的例子。

但是,您还必须质疑确实是否需要此类功能。

来自 Effective Java 2nd Edition 第25项:首选列表到数组

  

总之,数组和泛型具有非常不同的类型规则。数组是协变的和具体化的,泛型是不变的和被删除的。因此,数组提供运行时类型安全性,但不提供编译时类型安全性,反之亦然。一般来说,数组和泛型不能很好地混合。如果你发现自己混淆它们并得到编译时错误和警告,你的第一个冲动应该是用列表替换数组。

您应该阅读整个项目,以便对该主题进行更全面的处理。