返回某个值的泛型类方法

时间:2017-01-18 06:55:34

标签: java generics

我收到了ClassCastException。我是按照这个答案但没有做对的。 Cast Object to Generic Type for returning
BubbleSort.java

import java.util.ArrayList;
import java.util.List;

public class BubbleSort<T extends Number> {

    public List<T> list;

    @SuppressWarnings("serial")
    public BubbleSort() {
        list = new ArrayList<T>() {
        };
    }

    public void add(T obj) {
        list.add(obj);
    }

    public void sort() {
        for (int i = 0; i < list.size(); i++) {
            for (int j = 0; j < list.size() - 1; j++) {
                if (list.get(j).intValue() > list.get(j + 1).intValue()) {
                    T swapElement = list.get(j);
                    list.set(j, list.get(j + 1));
                    list.set(j + 1, swapElement);
                }
            }
        }
    } 

    public <T> T getArray(Class<T> clazz){
        T[] returnArray = (T[]) list.toArray();
        return clazz.cast(returnArray);
}

}

MainPorgram.java

import java.lang.reflect.Array;


public class MainProgram {

    public static void main(String args[]){
        BubbleSort<Integer> bubbleSort = new BubbleSort<>();
        bubbleSort.add(new Integer(1));
        bubbleSort.add(new Integer(2));
        bubbleSort.add(new Integer(6));
        bubbleSort.add(new Integer(5));
        bubbleSort.add(new Integer(4));
        bubbleSort.add(new Integer(3));
        Class<Integer[]> intArrayType = (Class<Integer[]>) Array.newInstance(Integer.TYPE, 0).getClass(); 
        Integer[] sortedArray = (Integer[]) bubbleSort.getArray(intArrayType);
        for(int i = 0 ; i < sortedArray.length; i++){
            System.out.println(sortedArray[i]);
        }
    }

}

控制台

  

线程“main”中的异常java.lang.ClassCastException:无法强制转换   [Ljava.lang.Object;到[我在java.lang.Class.cast(未知来源)at   BubbleSort.getArray(BubbleSort.java:32)at   MainProgram.main(MainProgram.java:15)

3 个答案:

答案 0 :(得分:2)

您的代码中存在相当多的混淆和错误的假设。如果您使用的是Java 8,我会建议一种更简单的工作方法,而不是详细说明所有这些(有些已经在其他答案中介绍过),

public class BubbleSort<T extends Number> {

    public List<T> list;

    public BubbleSort() {
        list = new ArrayList<T>();
    }

    //...

    public T[] getArray(IntFunction<T[]> arrayGenerator) {
        return list.stream().toArray(arrayGenerator);
    }
}

public class MainProgram {

    public static void main(String args[]) {
        BubbleSort<Integer> bubbleSort = new BubbleSort<>();
        //...
        Integer[] sortedArray = bubbleSort.getArray(Integer[]::new);
        //...
    }
}

答案 1 :(得分:1)

  

无法将[Ljava.lang.Object;投射到[I ...

该消息可能会使您感到困惑。此处[Ljava.lang.Object;实际上表示类型Object[][I表示int[]。这些是Java 类型签名,可以根据https://stackoverflow.com/a/8066268/224671进行解码。

因此,错误消息是抱怨您正试图将Object[]投射到int[]。您引用int类型的唯一位置是此行:

    Class<Integer[]> intArrayType = 
           (Class<Integer[]>) Array.newInstance(Integer.TYPE, 0).getClass(); 

问题是您使用Integer.TYPE返回int的类型,因此您获得的课程将为Class<int[]>。要使用实际的Integer类,请写:

    Class<Integer[]> intArrayType = 
           (Class<Integer[]>) Array.newInstance(Integer.class, 0).getClass(); 
    //                                                  ^~~~~

(有关差异,请参阅Difference between Integer.class and Integer.TYPE。)

请注意,由于您已经知道要处理Integer[]课程,因此您无需致电.getClass(),这就足够了:

Class<Integer[]> intArrayType = Integer[].class;

但这仍然是错误的,例如在

public <T> T getArray(Class<T> clazz){
    T[] returnArray = (T[]) list.toArray();

你将主张获得Integer[][](以及我将不会详细讨论的更多问题)...请参阅@Eran's answer以获得正确的解决方案。

答案 2 :(得分:0)

你有几个问题。

主要问题是list.toArray()返回Object[],您无法将其强制转换为其他类型的数组。您应该使用<T> T[] toArray(T[] a)来获取正确类型的数组。

您的代码的另一个问题是在方法<T> T getArray(Class<T> clazz)中声明的泛型参数隐藏了在类级别(class BubbleSort<T extends Number>)中声明的同名的泛型参数。

这是一个有效的建议修补程序:

public T[] getArray(Class<T> clazz) {
    return (T[]) list.toArray((T[])Array.newInstance (clazz, list.size()));
}

....

Integer[] sortedArray = bubbleSort.getArray(Integer.class);