You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

OCA Java SE 8备考疑问:数组引用与类型转换代码报错解析

关于Java数组协变与ArrayStoreException的解惑

让我一步步拆解你这段代码,帮你搞懂Error 2的本质:

先理清代码中每个变量的「编译类型」和「实际指向的对象类型」

这是理解问题的核心:

  • String[] strings = { "stringValue" };:创建了一个**实际类型为String[]**的数组对象,strings引用的编译类型也是String[],完全匹配。
  • Object[] objects = strings;:这里用到了Java数组的「协变性」——子类数组可以赋值给父类数组类型的引用。注意:objects的编译类型是Object[],但它实际指向的对象还是原来的String[]数组,并没有把String[]转换成Object[]对象,只是换了个“父类视角”来引用它。
  • String[] againStrings = (String[]) objects;:这是合法的向下转型,因为objects实际指向的就是String[],所以编译和运行都不会报错,againStrings重新用String[]的视角引用了同一个数组。

为什么Error 1编译不通过,Error 2编译通过但运行报错?

  • Error 1:againStrings的编译类型是String[],编译器明确知道这个数组只能存储String或其子类对象,StringBuilder和String没有继承关系,所以直接在编译阶段就阻止了这种操作,很容易理解。
  • Error 2:
    • 编译阶段:objects的编译类型是Object[],编译器认为Object[]可以存储任何Object的子类(StringBuilder确实是Object的子类),所以编译通过。
    • 运行阶段:Java数组是「具体化类型」,运行时会保留数组本身的实际类型信息。当你尝试往数组里存元素时,JVM会检查这个元素的类型是否符合数组的实际类型(也就是String[])。StringBuilder不是String的子类,不符合要求,所以会抛出ArrayStoreException。

用通俗的例子类比

就像你把一只猫装在标着「动物」的笼子里(Object[] objects = strings),笼子的标签是「动物笼」(编译类型Object[]),但里面实际装的还是猫(实际类型String[])。你不能把狗(StringBuilder)放进这个笼子里,因为笼子本质是用来装猫的,哪怕标签写的是动物笼。

内容的提问来源于stack exchange,提问作者TPA

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 06:25:45