Java 8:验证字节码时将 String[] 和 int[] 合并到 Object[] 中

Emi*_*mil 6 java jvm bytecode jvm-bytecode

我正在阅读 JVM 版本 8 规范的第 4.10.2.2 节(https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html)如何验证字节码。在这种情况下,当堆栈现在包含一个槽时,如果来自一个源,则包含一个 int[] ;如果来自另一个源,则包含一个 String[] ,控制流中会发生什么情况。

我阅读了以下内容,该内容在 JVM 版本 7 文档中不存在:

如果对应的值都是数组引用类型,则检查它们的维度。如果数组类型具有相同的维度,则合并的值是对数组类型实例的引用,该数组类型是两种数组类型的第一个公共超类型。(如果其中一个或两个数组类型具有原始元素类型,则使用 Object 作为元素类型。)

...

甚至int[]和String[]也可以合并;结果是 Object[],因为在计算第一个公共超类型时使用了 Object 而不是 int。

这对我来说没有任何意义,因为这意味着 int[] 可以转换为 Object[]。但在 Java 中,原始类型的数组不能转换为 Object[]。

谁能解释一下这背后的理由吗?

Ant*_*ony 3

我不确定为什么该语言出现在规范中,但它没有描述 JVM 实际行为的方式(这是有道理的,因为正如您所指出的,所描述的行为是无意义的)。

你可以在这里找到推理字节码验证器源代码,它自 2013 年以来一直没有改变。

作为额外检查,我创建了一个测试文件,该文件合并 int[] 和 String[],然后将 String 存储在结果中。正如预期的那样,我收到了验证错误(Java 版本 1.8.0_111)。