泛型类型函数的return语句出错

时间:2014-04-09 13:56:23

标签: java generics

我正在尝试创建一个泛型函数,我传递一个数组(int [],String [])并使用TreeSort获取它的排序版本。我甚至没有机会开始调试它,因为mainclass 拒绝接受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 [])

所以我尝试将unsortedNumssortedNumsint更改为Integer(为什么这很重要?),现在运行它会产生此错误:

错误2

  

线程“main”中的异常java.lang.ClassCastException:[Ljava.lang.Object;无法转换为[Ljava.lang.Comparable;

在线

T[] result = (T[]) new Object[arr.length];

5 个答案:

答案 0 :(得分:2)

在Java中的泛型方法中,不允许创建泛型类型的数组。您试图通过创建一个Object数组并将其转换为泛型类型来绕过此规则,但编译器太聪明并阻止了这一点。这个规则的原因是泛型类型很可能是一个接口,因此运行时不会知道要创建哪个类。

对于您的示例,如果您确实需要按原样保留未排序的数组并返回副本(通常,就地排序以便您只编辑原始数组),您可以让用户传递类型通用的(如sp00m的答案),或让用户提供目标数组作为参数,这样你就不需要自己创建一个数组。

IMO,这里的最佳做法是让您的排序到位,而不是返回数据的排序副本。

答案 1 :(得分:1)

而不是:

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);

答案 2 :(得分:1)

在Java中,数组在运行时知道它们的组件类型(组件类型是实际运行时数组类型的一部分),因此您需要在运行时指定组件类型以创建该类型的数组。

@spoom的答案向您展示了如何在给定传递给函数的类对象的情况下创建数组。但是,您实际上已经拥有该信息而未单独传递。参数arr的类型为T[],这意味着数组对象的实际运行时类型必须是T[]或其子类。我们可以从中提取组件类型并使用它来创建新数组:

T[] result = (T[]) Array.newInstance(arr.getClass().getComponentType(), arr.length);

例如,这是Arrays.copyOf()和相关功能的工作原理。

答案 3 :(得分:0)

你不能在泛型中使用原始类型(int)。尝试使用对象包装器,例如

Integer[] unsortedNums = {6,3,7,4,1,2,9,8,5}; Integer[] sortedNums = tree2.treeSort(unsortedNums);

答案 4 :(得分:0)

组合泛型和数组在Java中存在问题;查看文章Restrictions on Generics了解详情。

至于解决问题,最简单的方法是不使用数组而是使用List。例如:

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;
}

请注意,我没有测试过逻辑。