描述

理解
题目中的这段程序在编译器正常,运行时异常。错误出现在 b[1] = Integer.valueOf(42); 这一行代码, a 赋值给 b,a 和 b 指向同一对象 new String[2],而 String[] 的实现是不支持 set integer 操作。
这行引发运行时异常。从实现角度来说,Java的数组是协变的:也就说Java的类型系统认为子类数组可以被赋值给父类数组。而这种赋值和对象的多态类似,它并不会实际改变数组元素的实际类型,于是乎在上述的例子中尽管b表面上是Object[]类型,但是运行时它的实际类型是String[],内部元素也只能添加字符串(因为Java的数组不同与泛型,数组是存在运行时类型检查的),于是就引发了这种现象:编译期编译通过(因为表面的类型检查认为没有什么问题),运行时抛出异常(把事实上的Integer对象存进了String数组)。
作者:陆萌萌
链接:https://www.zhihu.com/question/371957442/answer/1017620831
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
如果想要编译时报错,我们可以用 List 代替 Array:
public class TestJava {
public static void f() {
String[] a = new String[2];
Object[] b = a;
a[0] = "hi";
b[1] = Integer.valueOf(42); // 此处运行时异常
System.out.println(a);
System.out.println(b);
}
public static void o() {
List<String> a = new ArrayList<>(2);
List<Object> b = a; // 此处类型检查时会报错
a.set(0, "hi");
b.set(1, Integer.valueOf(42));
}
public static void main(String[] args) {
f();
}
}
参考:
一道 Java 面试题:https://www.yinwang.org/blog-cn/2020/02/13/java-type-system
知乎讨论:https://www.zhihu.com/question/371957442
1133

被折叠的 条评论
为什么被折叠?



