Java 8:验证字节码时将字符串[]和int[]合并到对象[]中
我正在阅读JVM版本8()规范的第4.10.2.2节如何验证字节码。在这种情况下,当堆栈现在包含来自一个源的int[]和来自另一个源的String[]插槽时,控制流中会发生什么 我阅读了JVM版本7文档中没有的以下内容: 如果对应的值都是数组引用类型,则会检查它们的维度。如果数组类型具有相同的维度,则合并值是对数组类型实例的引用,该实例是两种数组类型的第一个公共超类型。(如果其中一种或两种数组类型都具有基元元素类型,则将对象用作元素类型。) 即使int[]和String[]也可以合并;结果是Object[],因为在计算第一个公共超类型时使用Object而不是int 这对我来说没有任何意义,因为这意味着int[]可以转换为对象[]。但在Java中,基元类型的数组不能强制转换为对象[]Java 8:验证字节码时将字符串[]和int[]合并到对象[]中,java,jvm,bytecode,jvm-bytecode,Java,Jvm,Bytecode,Jvm Bytecode,我正在阅读JVM版本8()规范的第4.10.2.2节如何验证字节码。在这种情况下,当堆栈现在包含来自一个源的int[]和来自另一个源的String[]插槽时,控制流中会发生什么 我阅读了JVM版本7文档中没有的以下内容: 如果对应的值都是数组引用类型,则会检查它们的维度。如果数组类型具有相同的维度,则合并值是对数组类型实例的引用,该实例是两种数组类型的第一个公共超类型。(如果其中一种或两种数组类型都具有基元元素类型,则将对象用作元素类型。) 即使int[]和String[]也可以合并;结果是O
有人能解释一下这背后的基本原理吗?我不知道为什么规范中有这种语言,但它没有描述JVM的实际行为方式(这很有意义,因为正如您所指出的,所描述的行为是无意义的) 您可以找到推断字节码验证器源代码,它自2013年以来一直没有改变
作为额外检查,我创建了一个测试文件,该文件合并int[]和String[],然后在结果中存储一个字符串。正如所料,我得到了一个验证错误(Java版本1.8.0_111)。可能是复制并粘贴了上一个项目,然后在尝试调整时出错了。我想,它实际上应该是“偶数int[]和String[]可以合并;结果是Object[],因为在计算第一个公共超类型时使用Object而不是int[]。@Holger这几乎是有道理的,但是上面的文本中也有错误。它表示“如果其中一个或两个数组类型都有一个基元元素类型,则使用Object作为元素类型。”。应该说,如果一个是基元类型,或者两个都是不同的基元类型,那么它们被认为是具有更少维度的对象数组。最后,前面规范的三句变体,即引用类型合并到公共超类型,比这更好。不清楚为什么会进行这种矛盾的扩展,特别是因为这部分是关于“类型推断验证器”的,它只适用于50版(Java6)及以下的类文件。这些旧类文件的规则在较新版本中不应更改。