【dup】和【pop】

dup:java

复制栈顶元素并压入栈程序员

 pop:this

出栈操做code

代码对象

public class JvmTest1{
    public static void testMethod(){
    new JvmTest1(); 
    }
}

编译字节码文件内存

javap -c JvmTest1.class
Compiled from "JvmTest1.java"
public class JvmTest1 {
  public JvmTest1();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void testMethod();
    Code:
       0: new           #2                  // class JvmTest1
       3: dup
       4: invokespecial #3                  // Method "<init>":()V
       7: pop
       8: return
}

1) 其中new指令在java堆上为JvmTest1对象分配内存空间,并将地址压入操做数栈顶;ci

2) 而后dup指令为复制操做数栈顶值,并将其压入栈顶,也就是说此时操做数栈上有连续相同的两个对象地址;编译器

3) invokespecial指令调用实例初始化方法<init>:()V,注意这个方法是一个实例方法,因此须要从操做数栈顶弹出一个this引用,也就是说这一步会弹出一个以前入栈的对象地址;it

4) 在调用完实例初始化方法后,将重复的实例引用又pop出栈了。由于我只new了一个JvmTest1对象,并无使用。不过这种状况基本不会出如今咱们的代码中,由于咱们建立的每个对象都应该是有用的。编译

5) 最后由return指令结束方法。

从上面的五个步骤中能够看出,须要从栈顶弹出两个实例对象的引用,这就是为何会在new指令下面有一个dup指令,其实对于每个new指令来讲通常编译器都会在其下面生成一个dup指令,这是由于实例的初始化方法确定须要用到一次,而后第二个留给程序员使用,例如给变量赋值,抛出异常等,若是咱们不用,那编译器也会生成dup指令,在初始化方法调用完成后再从栈顶pop出来。

相关文章
相关标签/搜索