gpt4 book ai didi

java - 为什么泛型方法更改了赋值中的参数化类型?

转载 作者:搜寻专家 更新时间:2023-11-01 02:13:32 24 4
gpt4 key购买 nike

在编写处理表单数据的通用方法时,我遇到了以下(如我所见)意外行为。给定以下代码:

public class Test {
public <T> void someGenericMethod(Integer a) {
@SuppressWarnings("unchecked")
T t = (T) a;
System.out.println(t);
System.out.println(t.getClass());
}

public static void main(String[] args) {
Test test = new Test();
test.<BigDecimal>someGenericMethod(42);
}
}

AFAIK,上面的代码应该在 T t = (T) a 行中生成一个 ClassCastException,因为 main 中的方法调用将参数化类型设置为 BigDecimal 和从 Integer 到 BigDecimal 的转换是不允许的,与我预期的相反,程序执行良好并打印了以下内容:

42
class java.lang.Integer

事实上,如果我将另一个参数添加到方法签名(如 String b)并进行另一个赋值 T t2 = (T) b,程序会打印

42
class java.lang.String

为什么 t 变量将其类型更改为 Integer(有可能是将 T 类型提升为 Object)?

欢迎对此行为进行任何解释

最佳答案

(T) a是一个未经检查的转换:由于type erasure ,运行时无法知道什么类型 T是,所以它实际上无法检查 a属于类型T .

编译器会在您这样做时发出警告;在你的情况下,你已经通过写 @SuppressWarnings("unchecked") 来抑制该警告.


编辑添加(回应下方评论中的进一步问题):

如果你想查看类型转换,你可以这样写:

public class Test {
public <T> void someGenericMethod(Class<T> clazz, Integer a) {
T t = clazz.cast(a);
System.out.println(t);
System.out.println(t.getClass());
}

public static void main(String[] args) {
Test test = new Test();
// gives a ClassCastException at runtime:
test.someGenericMethod(BigDecimal.class, 42);
}
}

通过传入 clazz ,您允许运行时检查类型转换;而且,更重要的是,您允许编译器推断 T来自方法参数,所以你不必写 test.<BigDecimal>someGenericMethod不再。

当然,调用该方法的代码仍然可以通过使用未经检查的转换来规避这一点:

public static void main(String[] args) {
Test test = new Test();
Class clazz = Object.class;
test.someGenericMethod((Class<BigDecimal>) clazz, 42);
}

但那就是 main的错,不是someGenericMethod的。 :-)

关于java - 为什么泛型方法更改了赋值中的参数化类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12205427/

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