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將此時的棧頂值彈出存入局部變量中去。