gpt4 book ai didi

java - 为什么 Integer 的泛型分配了 String 的值在打印时没有发出错误?

转载 作者:行者123 更新时间:2023-11-30 06:40:02 26 4
gpt4 key购买 nike

这个问题也可以看成是:为什么赋值为 Integer 的泛型 String 在打印时会出现运行时错误?但是这个问题的答案似乎很明显,标题问题对我来说却不是。我不明白为什么一个错误而不是另一个错误。这个问题适用于这个例子。假设您有一个参数化的 Box 类:

class Box <T> {
T value;

void setValue(T value) {
this.value = value;
}

T getValue() {
return value;
}
}

你有这个类的三个实例,一个没有类型参数,另外两个有 String 或 Integer。 String 和 Integer 的 Box 实例化为原始对象:

    Box rawBox = new Box();
Box <Integer> intBox = rawBox;
Box <String> stringBox = rawBox;

当我们通过原始引用传递 setValue() 值并通过各自的参数化引用打印 getValue() 时,我遇到的问题出现了:

    Integer integerVal = 4;
rawBox.setValue(integerVal);
System.out.println(intBox.getValue());
// System.out.println(stringBox.getValue()); // ClassCastException a Integer cannot be assigned to a String

rawBox.setValue("hi");
System.out.println(intBox.getValue()); // Why is there no ClassCastException for assigning a String to Integer?
System.out.println(stringBox.getValue());

ClassCastException 错误仅在打印 getValue() 时发出,而不是在调用 setValue() 时发出。那么,为什么实例化为 rawtype 的类型参数为 Integer 的参数化对象可以通过原始引用为其分配通用的 String 值,并且在打印 getValue() 时没有运行时错误,但是如果相同的参数化类型具有String 的类型参数和它的泛型通过原始类型分配了 Integer 的值,它会在打印 getValue() 时抛出 ClassCastException?

最佳答案

您可能了解 Box.value 在运行时是一个 Object,因此 Box.getValue 必须返回 Object.

PrintStream.println 对所有原始类型、ObjectString 都有重载。这大概是为了避免在打印的值已知为 String 时额外调用 Object.toString

想象一下,两次调用 println 生成的字节码会是什么样子:

Integer integerVal = 4;
rawBox.setValue(integerVal);
System.out.println(intBox.getValue());

在这种情况下,intBox.getValue() 返回 Object,因此我们将调用 println 的版本来接受对象。编译器知道返回值应该是 Integer,但这并不重要,因为没有接受 Integerprintln 重载.

System.out.println(stringBox.getValue());

这里,当stringBox.getValue()返回Object时,编译器知道它应该是一个String并且想要调用版本println 接受一个 String。这需要将返回值向下转换为 String,这会失败,因为它实际上是一个 Integer

关于java - 为什么 Integer 的泛型分配了 String 的值在打印时没有发出错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59021489/

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