Java 是否有Array.newInstance的通用版本?
我注意到在JavaJava 是否有Array.newInstance的通用版本?,java,arrays,generics,Java,Arrays,Generics,我注意到在JavaArray.newInstance()中返回的是Object,而不是T[]。这是可以理解的,因为这种方法是在Java支持泛型类型之前引入的 然而,令人惊讶的是,没有类似的通用版本。Java7的array.copyOf不一样-它复制参数的内容,而不是创建一个新的伪数组(其中包含所有空对象) 既然这个实现看起来微不足道,那么有什么理由不将它添加到JRE中呢?或者我就是找不到 更新 看来我应该提供我自己的“琐碎”实现来阻止对这个问题的误解 class MyArrayUtil {
Array.newInstance()
中返回的是Object
,而不是T[]
。这是可以理解的,因为这种方法是在Java支持泛型类型之前引入的
然而,令人惊讶的是,没有类似的通用版本。Java7的array.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...
}
类MyArrayUtil{
//类的通用版本
@抑制警告(“未选中”)
公共静态T[]newArrayOf(T[]T,int len){
return(T[])Array.newInstance(T.getClass().getComponentType(),len);
}
//对于int数组
公共静态int[]newArrayOf(int[]t,int len){
返回新整数[len];
}
//对于其他基本类型。。。
}
我不是把这段代码作为答案,因为它不是问题的答案。问题在于原因和/或现有代码,而不是如何实现
更新
我已经更新了代码,使其类似于
Arrays.copyOf
,其优点是程序员只需更改参数的类型,即可将代码调整为其他类型。此外,我还取消了对基元类型使用Array.newInstance
。否,您需要以某种方式将具体类型作为参数传递。正如您所提到的,Arrays.copyOf
显示了这一点
Class<T> type = determinteTheTypeSomehow();
return (T[]) Array.newInstance(type, length);
Class type=determinateTheTypeSomeHow();
return(T[])数组.newInstance(类型,长度);
番石榴提供。无论出于何种原因,Guava(或ApacheCommons)已经不是第一次提供JDK没有的常用助手了
你可能知道这一点,但谷歌的一些背景在将来会偶然发现:签名不能成为通用的原因是方法
Array.newInstance
,因此为了向后兼容,该方法的原始版本也应该返回Object
。如果将其概括为:
<T> T[] newInstance(Class<T> componentType, int length)
T[]newInstance(类componentType,int-length)
…那么返回类型将是Object[]
,而不是Object
。这将破坏向后兼容性,Java设计人员一直努力避免这样做
Array.copyOf
方法只在Java 1.6中出现,因此不必担心向后兼容性。基本原因是Array.newInstance()
不能像t[]newInstance(Class,int size)
那样声明,因为它可以用于创建原语数组。因此,例如,如果传入类型为class
的int.class
,那么从声明中可以期望它返回一个整数[]
对象。但是,函数实际上返回一个int[]
对象,该对象不是Integer[]
的子类型,因此它的类型错误
当然,他们可以添加一个额外的方法,如
newReferenceArrayInstance()
,该方法禁止基元类型(例如,当传递基元类型时抛出异常),因此可以安全地声明为返回T[]
。然而,这似乎只是为了避免未经检查的强制转换而添加了一个完全冗余的方法。不,不可能以编译时类型安全的方式实现这一点。例如,无法创建:列表[]
的新实例。编译器永远不会知道T
的类型,因此它不能保证客户端代码是安全的。因为array.copyOf
可以做这项工作,没有明显的理由不能做。array.copyOf
确定要复制的数组的具体类型。因此,使用类似的数组也可以。newInstanceOf
使用具体类型提供类型信息,正如我在问题中所说的,这个实现很简单。fwiw,Guava提供。数组。newInstance
需要一个类,就像数组一样。copyOf
需要T[]
,所以它们确实需要额外的参数,而不是类型参数。我只是想知道为什么我们不能有一个数组。接受类或T[]
的newInstance
(仅作为模板;里面的内容被忽略)。是的,我理解,但您试图使api适应您的需要,这是永远不会起作用的;)我承认这可能会令人沮丧,但事实就是这样。当我编写泛型类型时,我经常将具体的参数类型作为参数传递给构造函数,以用于此(和其他)目的。现在我想我明白了为什么让newArray
支持基元类型没有多大意义。如果要使用非泛型类型参数的类型创建新数组,只需使用new XYZ[]
。如果不是这样,您必须使用类类型,并且只有在这种情况下,newArray
功能才有用。如果您在方法签名/类定义中需要类似的参数/字段,这应该不会有问题。@EarthEngine也适用于基本类型,因为int.class
存在(与其他原语类似)。请参见示例。我知道这是可能的。但只有在运行时有类
实例时才有意义。在这种情况下,您的代码显式使用反射,而不仅仅是泛型。因为将擦除的返回类型从对象
更改为对象[]
是一个狭义的定义,它至少在理论上应该是二进制兼容的。