gpt4 book ai didi

java - 如何在 Java 泛型方法中正确返回泛型数组?

转载 作者:搜寻专家 更新时间:2023-10-31 08:09:46 24 4
gpt4 key购买 nike

我有以下返回通用数组的通用方法:

public static <T> T[] genericMethod1(List<T> input) {
T[] res = (T[]) new Object[input.size()];

int i = 0;
for (T t : input) {
res[i] = t;
i++;
}
return res;
}

public static <T> T genericMethod2(List<T> input) {
return input.get(0);
}

但稍后当我尝试使用以下方法获取结果数组时:

LinkedList<Integer> list = new LinkedList<Integer>();
list.addFirst(1);
list.addFirst(1);

Integer[] i = (Integer[]) genericMethod1(list); // 1) Runtime error
Integer j = genericMethod2(list); // 2) works

对于情况 1,我总是在运行时出错:

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.Integer;

任何人都可以解释为什么以及如何正确返回泛型数组?谢谢。

Below is my understanding, please correct me if I'm wrong.

As Tim mentioned, type erasure happened at compile time, so in bytecode, each T object is just type Object, meanwhile, compiler will add type cast from Object to T "properly".

Say T is an Integer, where T is declared, it's Object. For where it's referred, it's type cast (implicitly) to T.

EXCEPT that if T[] array is declared, it's Object[], and where the array is referred, it stays Object[]. No implicit cast to T[] happens.

最佳答案

你所看到的解释是由于一种叫做类型删除的东西。以下是您的 genericMethod() 在编译器执行类型删除后 的样子:

public static Object[] genericMethod(List input) {
Object[] res = new Object[input.size()];

int i = 0;
for (Object t : input) {
res[i] = t;
i++;
}
return res;
}

换句话说,此方法将返回类型为Object 的数组。无法将 Object[] 转换为 Integer[],因为它们不是同一类型。如果您希望您的方法能够动态返回您想要的类型,那么您可以使用 Array.newInstance()。这还需要传入您想要的数组类型作为输入参数:

public static <T> T[] genericMethod(Class<T> clazz, List<T> input) {
@SuppressWarnings("unchecked")
T[] res = (T[]) Array.newInstance(clazz, input.size());

int i = 0;
for (T t : input) {
res[i] = t;
i++;
}
return res;
}

现在您的代码片段将无错误地运行:

LinkedList<Integer> list = new LinkedList<Integer>();    
Integer[] i = genericMethod(Integer.class, list);

更新:

您的第二个方法 genericMethod2() 在类型删除后将如下所示:

public static Object genericMethod2(List input) {
return input.get(0);
}

它将返回输入列表的第一个元素,转换为Object。这是您对该方法的用法:

Integer j = genericMethod2(list);

编译器将尝试将 genericMethod2() 的输出转换为 Integer:

Integer j = (Integer)genericMethod2(list);

这个转换是合法的,因为每个Integer也是一个Object,而且它在这里成功,因为你传入了一个Integer的集合.第二种方法与您为我们强调的第一种方法不同。

关于java - 如何在 Java 泛型方法中正确返回泛型数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34939499/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com