Java 返回某些值的泛型类方法

Java 返回某些值的泛型类方法,java,generics,Java,Generics,我受到了同学们的尊敬。我一直在遵循这个答案,但没有得到正确的答案。 BubbleSort.java import java.util.ArrayList; import java.util.List; public class BubbleSort<T extends Number> { public List<T> list; @SuppressWarnings("serial") public BubbleSort() {

我受到了同学们的尊敬。我一直在遵循这个答案,但没有得到正确的答案。
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);
}

}
import java.util.ArrayList;
导入java.util.List;
公共类泡泡糖{
公开名单;
@抑制警告(“串行”)
公共泡泡港(){
列表=新的ArrayList(){
};
}
公共无效添加(T obj){
列表。添加(obj);
}
公共无效排序(){
对于(int i=0;ilist.get(j+1).intValue()){
T swaplement=list.get(j);
list.set(j,list.get(j+1));
列表组(j+1,Swaplement);
}
}
}
} 
公共T getArray(类clazz){
T[]returnArray=(T[])list.toArray();
返回clazz.cast(返回数组);
}
}
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]);
        }
    }

}
import java.lang.reflect.Array;
公共课程{
公共静态void main(字符串参数[]){
BubbleSort BubbleSort=新的BubbleSort();
添加(新整数(1));
添加(新的整数(2));
添加(新的整数(6));
添加(新的整数(5));
添加(新的整数(4));
添加(新的整数(3));
类intArrayType=(类)Array.newInstance(Integer.TYPE,0.getClass();
整数[]sortedArray=(整数[])bubbleSort.getArray(intArrayType);
对于(int i=0;i
控制台

线程“main”java.lang.ClassCastException中出现异常:无法强制转换 [Ljava.lang.Object;至[I at java.lang.Class.cast(未知源代码)at getArray(BubbleSort.java:32)位于 MainProgram.main(MainProgram.java:15)

无法在以下位置将
[Ljava.lang.Object;
强制转换为
[I

该消息可能会让您感到困惑。这里的
[Ljava.lang.Object;
实际上是指类型
对象[]
[I
是指
int[]
。这些是Java类型签名,可以根据


因此,错误消息抱怨您试图将
Object[]
转换为
int[]
。您引用
int
类型的唯一地方是这行:

    Class<Integer[]> intArrayType = 
           (Class<Integer[]>) Array.newInstance(Integer.TYPE, 0).getClass(); 
(有关区别,请参见。)

请注意,因为您已经知道您将处理
Integer[]
类,所以不需要调用
.getClass()
,只需这样就足够了:

Class<Integer[]> intArrayType = Integer[].class;
Class intArrayType=Integer[]类;
但这仍然是错误的,例如在

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

您将断言获得一个
整数[][][]
(还有更多问题,我不打算详细说明)…请参阅以获得正确的解决方法。

您有几个问题

主要问题是
list.toArray()
返回一个
对象[]
,不能将其强制转换为其他类型的数组。应该使用
t[]toArray(t[]a)
来获得正确类型的数组

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

下面是一个建议的解决方案:

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

....

Integer[] sortedArray = bubbleSort.getArray(Integer.class);
public T[]getArray(类clazz){
返回(T[])list.toArray((T[])Array.newInstance(clazz,list.size());
}
....
整数[]sortedArray=bubbleSort.getArray(Integer.class);

您的代码中存在相当多的混乱和错误假设。如果您使用的是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);
        //...
    }
}
公共类BubbleSort{
公开名单;
公共泡泡港(){
列表=新的ArrayList();
}
//...
公共T[]getArray(IntFunction arrayGenerator){
返回list.stream().toArray(arrayGenerator);
}
}
公共课程{
公共静态void main(字符串参数[]){
BubbleSort BubbleSort=新的BubbleSort();
//...
整数[]sortedArray=bubbleSort.getArray(整数[]:::新建);
//...
}
}

“未正确处理”是不够的。您需要发布堆栈跟踪,并指出程序中的哪一行引发异常。还要告诉我们您对该问题进行了哪些故障排除。您是否在调试器中单步执行了代码?这里有太多错误。
(BubbleSort.java:32)
这意味着错误发生在BubbleSort.java的第32行。这是哪一行?我认为使用数组的转换并不像您希望的那样有效-为什么不稍微更改一下-只需执行类似的操作:
Integer[]sortedArray=BubbleSort.list.toArray(新整数[BubbleSort.list.size());
问题在于getArray()方法始终返回一个对象数组,其中该数组中的对象是整数-但是,您希望使用整数定义数组。可能其他人会帮助您解决泛型问题,但我不知道如何解决。您只解决了部分问题。它仍然返回
Object[]
。这只会将错误更改为
无法强制转换[Ljava.lang.Object;到[Ljava.lang.Integer;
,上次编辑不正确。
T[]
确实是
Integer[]
,但由于类型擦除,强制转换被忽略。问题在下一行,
list.toArray()
,不能强制转换为
整数[]
。最好传入列表长度。另外,在
getArray()
@Eran中不需要外部强制转换,谢谢你!我知道了
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);
        //...
    }
}