当方法有 return 值时,invokestatic 是否将 return 值放在堆栈上?

Does invokestatic put the return value on the stack when the method has a return value?

我阅读了 JVM documetion 关于 invokevirtual 的内容。

我看到它会将条目表单堆栈弹出,然后没有人压入堆栈。

Operand Stack
    ..., objectref, [arg1, [arg2 ...]] →

    ...

仅当您调用没有 return 值的方法时才会出现这种情况吗?

————————————————————————————————

    public static void main(String[] args){
        System.out.println("Hello JVM!");
        Integer integer = 1;
    } 
  public static void main(java.lang.String[]);
    descriptor: ([Ljava/lang/String;)V
    flags: (0x0009) ACC_PUBLIC, ACC_STATIC
    Code:
      stack=2, locals=2, args_size=1
         0: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #3                  // String Hello JVM!
         5: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: iconst_1
         9: invokestatic  #5                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
        12: astore_1
        13: return
      LineNumberTable:
        line 6: 0
        line 7: 8
        line 8: 13

在上面的代码中:

8: iconst_1int 压入堆栈

9: invokestatic 弹出 int 表单栈 // 栈现在为空

12: astore_1

当方法有 return 值时,invokestatic 是否将 return 值放入堆栈?

嗯,从技术上讲不是,但实际上是。

invokestatic 仅在调用的方法为 native 时才将 return 值压入操作数堆栈(在本例中,这令人困惑地表示非 Java 代码)。

对于非本机方法(即所有在 Java 中编写的“正常”方法),该工作由 *return 操作码完成,这将是最后执行的指令(假设正常终止方法)。例如 areturn:

If no exception is thrown, objectref is popped from the operand stack of the current frame [...] and pushed onto the operand stack of the frame of the invoker.

由于常规 returns 仅通过 *return 操作码发生,所以非空方法的成功 invokestatic 保证将 return 值弹出到操作数堆栈。