[英]Error with return-statement of generic type function
我试图制作一个通用函数,将一个数组(int [],String [])传递给该函数,并使用TreeSort返回它的排序版本。 因为主类拒绝接受int []数组作为参数 ,所以我什至没有机会对其进行调试。
TreeSort
public T[] treeSort(T[] arr) {
T[] result = (T[]) new Object[arr.length];
for (int i = 0; i < arr.length; i++)
if (arr[i] != null)
add(arr[i]);
Iterator it = iterator();
int count = 0;
while (it.hasNext())
result[count++] = (T) it.next();
return (T[]) result;
}
主要
BinarySearchTree<Integer> tree2 = new BinarySearchTree<>();
int[] unsortedNums = {6,3,7,4,1,2,9,8,5};
int[] sortedNums = tree2.treeSort(unsortedNums);
错误
BinarySearchTree类型的方法treeSort(Integer [])不适用于参数(int [])
因此,我尝试将unsortedNums
和sortedNums
从int
更改为Integer
(为什么sortedNums
?),现在运行它会产生此错误:
错误2
线程“主”中的异常java.lang.ClassCastException:[Ljava.lang.Object; 无法转换为[Ljava.lang.Comparable;
在线
T[] result = (T[]) new Object[arr.length];
在Java的通用方法中,不允许创建通用类型的数组。 您正在尝试通过创建一个Object数组并将其强制转换为通用类型来规避此规则,但是编译器太聪明了,因此无法这样做。 该规则的原因在于,泛型类型很可能是接口,因此运行时不知道要创建哪个类。
以您的示例为例,如果您确实需要按原样保留未排序的数组并返回一个副本(通常,排序发生在原位,因此您只需编辑原始数组),则可以让用户传递通用类型(如sp00m的回答),或者让用户提供目标数组作为参数,因此您无需自己创建数组。
IMO,这里的最佳实践是使您的排序发生在适当的位置,而不是返回数据的排序后的副本。
代替:
T[] result = (T[]) new Object[arr.length];
您必须使用:
T[] result = (T[]) Array.newInstance(clazz, arr.length);
其中clazz
是嵌套元素的类型:
public T[] treeSort(T[] arr, Class<T> clazz) {...}
最后,在调用时,使用装箱的原语:
Integer[] unsortedNums = { 6, 3, 7, 4, 1, 2, 9, 8, 5 };
Integer[] sortedNums = treeSort(unsortedNums, Integer.class);
在Java中,数组在运行时知道其组件类型(组件类型是实际运行时数组类型的一部分),因此您需要在运行时指定组件类型以创建该类型的数组。
@spoom的答案向您展示了如何在传递给函数的类对象下创建数组。 但是,您实际上已经拥有该信息,而没有单独传递它。 参数arr
为T[]
类型,这意味着数组对象的实际运行时类型必须为T[]
或其子类。 我们可以从中提取组件类型并使用它来创建新的数组:
T[] result = (T[]) Array.newInstance(arr.getClass().getComponentType(), arr.length);
例如,这就是Arrays.copyOf()
和相关函数的工作方式。
您不能在泛型中使用基本类型(int)。 例如,尝试使用对象包装器
Integer[] unsortedNums = {6,3,7,4,1,2,9,8,5}; Integer[] sortedNums = tree2.treeSort(unsortedNums);
在Java中,将泛型和数组结合起来是有问题的。 查看文章通用限制 。
对于解决问题,最简单的方法不是使用数组,而是使用列表。 因此,例如:
public List<T> treeSort(List<T> list) {
List<T> result = new ArrayList<T>(list.size());
for (int i = 0; i < list.size(); i++)
if (list.get(i) != null)
result.add(list.get(i));
Iterator<T> it = list.iterator();
int count = 0;
while (it.hasNext())
result.set(count++, it.next());
return result;
}
提醒您,我尚未测试逻辑。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.