我注意到在Java Array.newInstance()
中返回Object
,而不是T[]
。这是可以理解的,因为在Java支持泛型类型之前引入了这个方法。
然而,令人惊讶的是,没有相同的通用版本。 Java 7的Arrays.copyOf
不一样 - 它复制参数的内容,而不是创建一个新的虚拟数组(里面包含所有空对象)。
由于实现这一点似乎微不足道,有没有理由不将其添加到JRE中?或者我找不到一个?
更新
我似乎会提供自己的“琐碎”实施来阻止对这个问题的误解。
class MyArrayUtil {
//Generic version for classes
@SuppressWarnings("unchecked")
public static <T> T[] newArrayOf(T[] t, int len){
return (T[]) Array.newInstance(t.getClass().getComponentType(), len);
}
//For array of int
public static int[] newArrayOf(int[] t, int len){
return new int[len];
}
//For other primitive types...
}
我不会将此代码作为答案发布,因为它不是问题的答案。问题是出于原因和/或现有代码,而不是如何实施。
更新
我已经更新了代码以使其类似于Arrays.copyOf
,并且优点是程序员可以简单地更改参数的类型以调整其他类型的代码。我也删除了Array.newInstance
对原始类型的使用。
答案 0 :(得分:8)
Guava提供just such a function。这不是Guava(或Apache Commons)第一次提供JDK没有的常用帮助器,无论出于何种原因。
你可能知道这一点,但是谷歌将来偶然发现这种情况的一些背景:签名不能通用的原因是方法Array.newInstance
returned Object
in Java 1.4,所以对于倒退兼容性,方法的原始版本也应该返回Object
。如果它被广泛化为:
<T> T[] newInstance(Class<T> componentType, int length)
...然后返回类型为Object[]
,而不是Object
。这会打破向后兼容性,Java设计人员一直很努力不去做。
Arrays.copyOf
方法仅与Java 1.6一起使用,因此不必担心向后兼容性。
答案 1 :(得分:4)
不,您需要以具体方式传递具体类型作为参数。正如您所提到的,Arrays.copyOf
显示了这一点。
Class<T> type = determinteTheTypeSomehow();
return (T[]) Array.newInstance(type, length);
答案 2 :(得分:3)
Array.newInstance()
无法像<T> T[] newInstance(Class<T> class, int size)
那样声明的基本原因是因为它可以用于创建基元数组。例如,如果您传入int.class
,其类型为Class<Integer>
,那么从声明中您可以期望它返回Integer[]
个对象。但是,该函数实际返回int[]
对象,该对象不是Integer[]
的子类型,因此它的类型错误。
当然,他们可以添加一个额外的方法,如newReferenceArrayInstance()
禁止基本类型(例如,在传递基本类型时抛出异常),因此可以安全地声明返回{{1 }}。但是,这似乎只是为了避免未经检查的演员而添加一个完全冗余的方法。