在这种情况下,哪一项是最佳实践?我想要一个未初始化的数组,其类型和长度与原始数组相同。
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
发布于 2010-04-19 08:47:47
AnyType[] anotherArray = (AnyType[])java.lang.reflect.Array.newInstance(
someArray.getClass().getComponentType(), someArray.length);发布于 2010-04-19 08:44:24
数组和泛型并不能很好地混合。这是因为数组是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而不是数组,因为List不会有相同的问题。将代码更改为:
public static void main(String args[]) {
foo(new ArrayList<Float>());
}
public static void foo(List<Number> list) {
list.add(3);
}并且代码无法编译,这是一个好得多的结果。
发布于 2010-04-19 10:03:22
一个很好的参考是查看AbstractCollection是如何实现 T[] Collection.toArray(T[])的
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);
//...因此,该技术使用:
Class Class.getComponentType()返回表示数组组件类型的Class。如果此类不表示数组类,则此方法返回null.
Object Array.newInstance(Class componentType, int... dimension)创建具有指定组件类型和维度的新数组。
(T[])演员。如果您一定要创建一个“泛型”数组,那么传递一个instanceof T[]并使用反射实例化另一个数组的技术就是Java Collections Framework所展示的方法。
然而,你也必须质疑你是否真的需要这样的功能。
摘自Effective Java2Edition:项目25:首选列表而不是数组
总之,数组和泛型有非常不同的类型规则。数组是协变的和具体化的,泛型是不变的和擦除的。因此,对于泛型,数组提供运行时类型安全,但不提供编译时类型安全,反之亦然。一般来说,数组和泛型不能很好地混合。如果您发现自己混合了它们,并收到编译时错误和警告,您的第一个冲动应该是用列表替换数组。
你应该阅读整篇文章,以便更全面地了解这一主题。
https://stackoverflow.com/questions/2664594
复制相似问题