java 使用 Array.newInstance() 创建一个新的泛型类型数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12789854/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Creating a new generic type array using Array.newInstance()
提问by Jimmy C
For practice, I'm trying to implement the merge sort algorithm but got stuck pretty fast when trying to instantiate a generic type array. I'm not entirely sure if my plan will work out, but right now the interesting part (or frustrating, depending on when you ask me) is the second row in the merge() method. The newInstance() method needs to know what class it should initiate as, but even if arr1.getClass() compiles perfectly fine, it won't work during runtime.
在实践中,我正在尝试实现合并排序算法,但在尝试实例化泛型类型数组时卡住了非常快。我不完全确定我的计划是否会成功,但现在有趣的部分(或令人沮丧,取决于你问我的时间)是 merge() 方法中的第二行。newInstance() 方法需要知道它应该作为哪个类启动,但即使 arr1.getClass() 编译得很好,它在运行时也不会工作。
public void mergeSort(T[] arr) {
T[] merged = merge(Arrays.copyOfRange(arr, 0, arr.length/2), Arrays.copyOfRange(arr, arr.length/2+1, arr.length-1));
}
@SuppressWarnings({"unchecked"})
public T[] merge(T[] arr1, T[] arr2) {
// A new array of type T that will contain a merged version of arr1 and arr2
T[] merged = (T[]) Array.newInstance(arr1.getClass(), arr1.length+arr2.length);
int i1 = 0, i2 = 0;
for (int i = 0; i < arr1.length + arr2.length; i++) {
if (arr1[i1].compareTo(arr2[i2]) < 0) {
merged[i] = arr1[i1];
i1++;
} else {
merged[i] = arr2[i2];
i2++;
}
}
return merged;
}
The error message is:
错误信息是:
Exception in thread "main" java.lang.ClassCastException: [[Ljava.lang.String; cannot be cast to [Ljava.lang.Comparable;
at sort.SortingAndSearching.merge(SortingAndSearching.java:94)
at sort.SortingAndSearching.mergeSort(SortingAndSearching.java:84)
at sort.SortingAndSearching.main(SortingAndSearching.java:19)
回答by Alex Coleman
Think I see the issue... When you do Array.newInstance(...)
, it takes in the component type (in your case, you want it to be String). However, you're handing the array class (arr1 is of type String[], and you're doing arr1.getClass()
). Instead, do
认为我看到了问题......当你这样做时Array.newInstance(...)
,它接受组件类型(在你的情况下,你希望它是字符串)。但是,您正在处理数组类(arr1 是 String[] 类型,您正在处理arr1.getClass()
)。相反,做
arr1.getClass().getComponentType()
to get the String
class out of String[]
让String
班级离开String[]
Per javadoc:
每个javadoc:
static Object newInstance(Class<?> componentType, int[] dimensions)
componentType - the Class object representing the component typeof the new array
componentType - 表示新数组的组件类型的 Class 对象
回答by vainolo
I copied and pasted the code you gave and it doesn't even compile. After doing some fixes, I came to this:
我复制并粘贴了您提供的代码,但它甚至无法编译。在做了一些修复之后,我来到了这个:
public class Test {
public <T extends Comparable> void mergeSort(T[] arr) {
T[] merged = merge(Arrays.copyOfRange(arr, 0, arr.length / 2), Arrays.copyOfRange(arr, arr.length / 2 + 1, arr.length - 1));
}
public <T extends Comparable> T[] merge(T[] arr1, T[] arr2) {
// A new array of type T that will contain a merged version of arr1 and arr2
T[] merged = (T[]) Array.newInstance(arr1.getClass(), arr1.length + arr2.length);
int i1 = 0, i2 = 0;
for(int i = 0; i < arr1.length + arr2.length; i++) {
if(arr1[i1].compareTo(arr2[i2]) < 0) {
merged[i] = arr1[i1];
i1++;
} else {
merged[i] = arr2[i2];
i2++;
}
}
return merged;
}
}
Since you are using the compareTo
method, you must tell the compiler that T
implements this interface.
由于您正在使用该compareTo
方法,您必须告诉T
实现此接口的编译器。