Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 8:验证字节码时将字符串[]和int[]合并到对象[]中_Java_Jvm_Bytecode_Jvm Bytecode - Fatal编程技术网

Java 8:验证字节码时将字符串[]和int[]合并到对象[]中

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版本8()规范的第4.10.2.2节如何验证字节码。在这种情况下,当堆栈现在包含来自一个源的int[]和来自另一个源的String[]插槽时,控制流中会发生什么

我阅读了JVM版本7文档中没有的以下内容:

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

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

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


有人能解释一下这背后的基本原理吗?

我不知道为什么规范中有这种语言,但它没有描述JVM的实际行为方式(这很有意义,因为正如您所指出的,所描述的行为是无意义的)

您可以找到推断字节码验证器源代码,它自2013年以来一直没有改变


作为额外检查,我创建了一个测试文件,该文件合并int[]和String[],然后在结果中存储一个字符串。正如所料,我得到了一个验证错误(Java版本1.8.0_111)。

可能是复制并粘贴了上一个项目,然后在尝试调整时出错了。我想,它实际上应该是“偶数int[]和String[]可以合并;结果是Object[],因为在计算第一个公共超类型时使用Object而不是int[]。@Holger这几乎是有道理的,但是上面的文本中也有错误。它表示“如果其中一个或两个数组类型都有一个基元元素类型,则使用Object作为元素类型。”。应该说,如果一个是基元类型,或者两个都是不同的基元类型,那么它们被认为是具有更少维度的对象数组。最后,前面规范的三句变体,即引用类型合并到公共超类型,比这更好。不清楚为什么会进行这种矛盾的扩展,特别是因为这部分是关于“类型推断验证器”的,它只适用于50版(Java6)及以下的类文件。这些旧类文件的规则在较新版本中不应更改。