为何编译器无法检测到数组强转引发的ClassCastException?
为什么
String[] test = (String[]) new Object[10];编译通过但运行抛出ClassCastException? - Java数组是协变类型:
String[]属于Object[]的子类(因为String继承自Object),这和String是Object子类的逻辑一致。 - 编译器只做静态类型校验:它只会判断转型的两个类型是否在同一继承链上——这里
String[]和Object[]存在继承关系,所以允许这种向下转型,就像String s = (String) new Object();能编译通过一样。编译器没法提前知道运行时的实际实例类型,只能确认类型转换的语法和继承逻辑是否合法。 - 但数组在运行时会保留实际类型信息:你创建
new Object[10]时,这个数组的实际类型就是Object[],运行时会严格校验数组的实际类型和目标转型类型是否匹配。由于Object[]的实际类型并不是String[](反过来String[]可以转成Object[],因为它本身就是Object[]的子类实例),所以运行时直接抛出ClassCastException。
总结:编译器只看类型间的继承关系,允许合法的向下转型操作;而运行时会检查实例的真实类型,发现不匹配就报错。
内容的提问来源于stack exchange,提问作者K6J4
相关产品推荐
相关产品推荐

