首页 > 解决方案 > 方法有返回值时,invokestatic是否将返回值放入栈中?

问题描述

我已经阅读关于invokevirtual.

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

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

    ...

仅当您调用没有返回值的方法时才如此吗?

————————————————————————————————————</p>

    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

上面代码中:</p>

8 :iconst_1入栈int

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

12:astore_1

方法有返回值时,invokestatic是否将返回值放入栈中?

标签: javajvm

解决方案


好吧,从技术上讲不是,但实际上是的。

invokestaticnative如果调用的方法是(在这种情况下混淆地表示非 Java 代码),则仅将返回值推送到操作数堆栈上。

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

如果没有抛出异常,objectref 将从当前帧的操作数堆栈中弹出 [...] 并推入调用者帧的操作数堆栈。

由于常规返回仅通过*return操作码发生,因此可以保证成功invokestatic的非 void 方法将返回值弹出到操作数堆栈中。


推荐阅读