gpt4 book ai didi

java - 使用 Java-8 时可变参数中的 ClassCastException

转载 作者:行者123 更新时间:2023-12-01 23:02:50 35 4
gpt4 key购买 nike

以下代码对于 m2() 工作正常,但当我使用 m1() 时抛出 ClassCastException

m1m2 之间的唯一区别是参数数量。

public class Test  {

public static void m1() {
m3(m4("1"));
}

public static void m2() {
m3(m4("1"), m4("2"));
}

public static void m3(Object... str) {
for (Object o : str) {
System.out.println(o);
}
}

public static <T> T m4(Object s) {
return (T) s;
}

public static void main(String[] args) {
m1();
}
}

我的问题是 - 当我们使用泛型时,可变参数不适用于单个参数吗?

PS:这与 ClassCastException using Generics and Varargs 无关

最佳答案

让我们暂时跳过您忽略了未经检查的转换警告的事实,并尝试理解为什么会发生这种情况。

在此声明中:

Test.m3(Test.m4("1"));

有一种推断类型,即m4的返回类型。如果要在 m3 调用上下文之外使用它,如下所示:

Test.m4("1"); // T is Object

T 被推断为 Object。可以使用类型见证来强制编译器使用给定类型:

Test.<String>m4("1"); // T is String

...或者通过在赋值上下文中使用表达式:

String resString = Test.m4("1"); // T is String
Integer resInt = Test.m4("1"); // T is Integer <-- see the problem?

...或在调用上下文中:

Integer.parseInt(Test.m4("1")); // T is String
Long.toString(Test.m4("1")); // T is Long

现在,回到 Test.m3(Test.m4("1"));:我找不到这方面的引用,但我相信编译器被迫生成 T解析为m3的参数类型,即Object[]。这意味着 必须m3 的参数类型一致的 T 因此被解析为 Object[],这使得您将泛型类型指定为:

Test.m3(Test.<Object[]>m4("1")); // this is what is happening

现在,因为 m4 没有返回 Object[],所以 m3 正在接收 String,这导致不可避免的ClassCastException

如何解决?

解决此问题的第一种方法是为 m4 指定正确的类型参数:

Test.m3(Test.<String>m4("1")); 

这样,String 就是 m4 的返回类型,并且使用单个 String 调用 m3对象(对于 Object... var-arg),就像您编写的一样:

String temp = m4("1");
m3(temp);

@Ravindra Ranwala 已删除的答案中建议了第二种方法。在我看来,这可以归结为注意编译器警告:

public static <T> T m4(Object s) {
return (T) s; // unchecked cast
}

未经检查的强制转换警告只是告诉您编译器(和运行时)不会强制执行类型兼容性,只是因为 T 不知道您在哪里进行强制转换。以下版本是类型安全的,但它也使编译器使用 String 作为 m4 的返回类型以及 m3< 的参数类型:

public static <T> T m4(T s) {
return s;
}

这样,m3(m4("1"));仍然使用Object...作为m3的参数类型,同时保留 String 返回类型为 m4(即,字符串值用作 Object 数组的第一个元素)。

关于java - 使用 Java-8 时可变参数中的 ClassCastException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59386790/

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