5

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

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

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

...

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

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

谁能解释这背后的理由?

4

1 回答 1

3

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

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

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

于 2017-08-27T15:50:42.400 回答