java字節碼構造對象爲什麼需要dup命令


package jvm.study;

public class Test {

/**
* @param args
*/
public static void main(String[] args) {
Test t = new Test();
}

}



這段代碼所產生的字節碼如下

// Compiled from Test.java (version 1.6 : 50.0, super bit)
public class jvm.study.Test {

// Method descriptor #6 ()V
// Stack: 1, Locals: 1
public Test();
0 aload_0 [this]
1 invokespecial java.lang.Object() [8]
4 return
Line numbers:
[pc: 0, line: 3]
Local variable table:
[pc: 0, pc: 5] local: this index: 0 type: jvm.study.Test

// Method descriptor #15 ([Ljava/lang/String;)V
// Stack: 2, Locals: 2
public static void main(java.lang.String[] args);
0 new jvm.study.Test [1]
3 dup
4 invokespecial jvm.study.Test() [16]
7 astore_1 [t]
8 return
Line numbers:
[pc: 0, line: 9]
[pc: 8, line: 10]
Local variable table:
[pc: 0, pc: 9] local: args index: 0 type: java.lang.String[]
[pc: 8, pc: 9] local: t index: 1 type: jvm.study.Test
}

這裏可以看到其中main方法主要做的

0 new jvm.study.Test [1]
3 dup
4 invokespecial jvm.study.Test() [16]
7 astore_1 [t]
8 return

這裏有個dup指令。其作用就是複製之前分配的jvm.study.Test空間的引用並壓入棧頂。那麼這裏爲什麼需要這樣麼做呢?因爲invokespecial指令通過[16]這個常量池入口尋找到了jvm.study.Test()構造方法,構造方法雖然找到了。但是必須還得知道是誰的構造方法,所以要將之前分配的空間的應用壓入棧頂讓invokespecial命令應用才知道原來這個構造方法是剛纔創建的那個引用的,調用完成之後將棧頂的值彈出。
之後調用astore_1將此時的棧頂值彈出存入局部變量中去。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章