当我注意到简单的表达式 Math.max(0,1) 变成了以下字节码指令时,我正在研究 java 字节码。
ICONST_0,
ICONST_1,
INVOKESTATIC(java/lang/Math.max)
我的问题是如果java使用后进先出堆栈,这意味着1现在将在堆栈上的0之前,这意味着vm在调用max时必须反转堆栈上项目的顺序在 1 之前获取 0 的指令。但是在规范中,它说要注意这一点,我的假设是正确的。
参数堆栈只是一个抽象。正如您所观察到的,当一个操作需要 n 个参数时,顶部的 n 个参数会从堆栈中取出并从下到上使用。这不仅适用于 invokestatic,而且适用于每条字节码指令。
例如下面的序列
iconst_0 iconst_1 iconst_2 isub
Pushes 0,1, and 2 onto the stack. The isub instruction pops off the top two values, 1, and 2 and uses them from bottom to top so the result is 1-2 = -1. Therefore, the end result is a stack containing 0, -1.
If you're interested in details like this, you should try reading the JVM specification.
如果java使用后进先出堆栈
还有一种吗?
这意味着当 vm 调用 max 指令以在 1 之前获取 0 时,它必须反转堆栈中项目的顺序
不,它没有。零已经在“之前”了。任何方法的参数都按照它们在源文本中出现的顺序被推送,就像局部变量声明一样。我不知道你为什么认为需要任何逆转。它不是。