<index> <opcode> [ <operand1> [ <operand2>... ]] [<comment>]
index 表示偏移量 行號 等
opcode 表示操做碼
operandX表示操做數
comment 爲註釋
|
其中 index 行號/偏移量 能夠做爲控制跳轉指令的跳轉目標 好比 goto 8 表示跳轉到索引爲8的指令上 |
public static void main(String[] args) { int i = -1; int j = 3; int k = 5; int l = 127; int m = 32767; int n = 32768; int add = i+j; int sub = i-j; int mul = j*k; int div = j/k; int rem = k%j; int neg = ~j; int inc = i++; }
public static void main(String[] args) { boolean bNum = true; char cNum = 2; byte byteNum = 127; short sNum = 32767; int iNum = 100; long lNum = 65536; float fNum = 2.5f; double dNum = 6.8;
char c1 = (char)byteNum; char c2 = (char)sNum; char c3 = (char)iNum; char c4 = (char)lNum; char c5 = (char)fNum; char c6 = (char)dNum; byte b1 = (byte)cNum; byte b2 = (byte)sNum; byte b3 = (byte)iNum; byte b4 = (byte)lNum; byte b5 = (byte)fNum; byte b6 = (byte)dNum; short s1 = (short)cNum; short s2 = (short)byteNum; short s3 = (short)iNum; short s4 = (short)lNum; short s5 = (short)fNum; short s6 = (short)dNum; int i1 = (int)cNum; int i2 = (int)byteNum; int i3 = (int)sNum; int i4 = (int)lNum; int i5 = (int)fNum; int i6 = (int)dNum; long l1 = (long)byteNum; long l2 = (long)cNum; long l3 = (long)sNum; long l4 = (long)iNum; long l5 = (long)fNum; long l6 = (long)dNum; float f1 = (float)byteNum; float f2 = (float)cNum; float f3 = (float)sNum; float f4 = (float)iNum; float f5 = (float)lNum; float f6 = (float)dNum; double d1 = (double)byteNum; double d2 = (double)cNum; double d3 = (double)sNum; double d4 = (double)iNum; double d5 = (double)lNum; double d6 = (double)fNum; }
class Super{ } class Sub extends Super{ } new Object(); new Super(); Super s = new Super(); new Double(1.5); new Sub(); Sub sub = new Sub();
new Object();
new Super();
沒有賦值給局部變量 僅僅是建立對象 調用new以後,堆中對象的引用保存在棧頂
而後調用構造方法invokespecial
Super s = new Super();
同上面的,須要調用new
由於還須要保存到局部變量
因此new以後 先copy一個,也就是dup
而後調用構造方法 invokespecial
而後從操做數棧保存到局部變量 store
|
Super super1 = new Super(); Sub sub = new Sub(); //父類引用能夠指向子類 //子類引用不能指向父類 //可是對於指向子類的父類引用 能夠經過類型轉換爲子類 Super subToSuper = sub; Sub superToSub = (Sub) subToSuper;
0 建立Spper 3 複製 4 調用構造方法 7 保存到1號局部變量 8 建立Sub 11 複製 12調用構造方法 15 保存到2號局部變量 16 2號加載到操做數棧 17保存到3號局部變量 18加載3號局部變量到棧 19 checkcast 進行校驗確認是否能夠轉換爲指定類型 不然報錯拋 classCastException 22 再次保存到局部變量 |
void intWhile() { int i = 0; while (i < 100) { i++; } } void intDoWhile() { int i = 0; do { i++; } while (i < 100); } void intFor() { int j = 0; for(int i =0;i<100;i++) { j++; } }
intWhile()方法 0. 加載常量0 到操做數棧 1.保存操做數棧元素到1號局部變量 i= 0; 2.直接跳轉到第8行 8.1號局部變量加載到操做數棧 也就是i 做爲第一個元素 9.加載常量100到操做數棧 也就是100做爲第二個元素 11.比較大小,若是前者小於後者 也就是若是 i <100 知足 跳轉到第5行 不然順序執行到14 return 5.給1號局部變量以增量1 增長 而後 8-->9-->11-->5-->8-->9-->11......往復循環 直到條件不知足,從11 跳轉到14 結束 |
intDoWhile() 0.加載常量0到操做數棧 1.保存常量0 到1號局部變量 2.給1號局部變量以增量1 進行自增 5.1號局部變量加載到操做數棧 6.常量100加載到操做數棧 8,比較大小 若是前者小於後者也就是 1號局部變量 i<100 跳轉到第2行 而後進行往復循環,直到條件不知足,而後順序到return |
intFor() 0. 加載常量0 到操做數棧 1. 保存棧頂元素到1號局部變量 j=0; 2. 加載常量0到操做數棧 3. 保存棧頂元素到2號局部變量i=0; 4. 跳轉到13行 13. 加載2號局部變量到操做數棧 14. 加載常量100到操做數棧 16. 比較大小,若是前者 2號局部變量 i <100 跳轉到7 7. 1號局部變量以增量1 自增 j++ 10. 2號局部變量以增量1 自增 i++ 13. 2號局部變量加載到操做數棧
14. 加載常量100到操做數棧
16. 比較大小,若是前者 2號局部變量 i <100 跳轉到7
往復循環 若是條件不知足 從16 順序到19 結束方法 return
|
public void fun() { int i = 0; if(i<2) { i++; }else { i--; } }
0, 加載常量0 到棧頂 1,保存棧頂元素 (0) 到1號局部變量 2. 加載1號局部變量到棧頂 3. 加載常量2 到棧頂 4,比較 若是大於後者等於跳轉到13 而後1號局部變量 自增1 而後下一步順序到16 return 不然就是順序執行到7 1號局部變量 增量爲-1 自增運算 而後到10 ,10爲跳轉到16 return |
public void invoker() { method(2); } public void method(int i) { if(i>5) { System.out.println(i); } }
invoker() 0,加載0號 局變量到棧 (上面基本都是第一個數據被保存到1號局部變量,0 號實際上是被this 佔用了) 1,加載常量2 到操做數棧 2.調用實例方法(I)V 5 return method(int) 0. 加載1號局部變量到操做數棧 1. 加載常量5 到操做數棧 2比較若是小於等於 跳轉到12行 直接返回 若是大於 那麼順序執行到5行 out 是類型爲PrintStream的 System中的靜態變量 8 加載1號局部變量到操做數棧 9 調用實例方法 println 是 PrintStream的實例方法 使用invokevirtual |
int i = 5; int j = 6; switch (i) { case 1: j = j + 1; break; case 3: j = j + 2; break; case 5: j = j + 3; break; default: j = j + 4; }
0,1,2,4 分別將 5 和 6 加載並存儲到1號和2號局部變量 5.加載1號局部變量到棧 對應 switch (i) { 而後根據tableswitch 表 進行跳轉 雖然咱們只有1,3,5 可是設置了1到5 ,對於2 和 4 直接跳轉到default 40: 2號局部變量 +1 順序到43 43: 跳轉到61 return
46: 2號局部變量 +2
順序到49
49: 跳轉到61 return
52: 2號局部變量 +3
順序到55
55: 跳轉到61 return
58 2號局部變量 +4 順序到61 return |
int j = 6; String string = "hehe"; switch (string) { case "A": j = j + 1; break; case "hehe": j = j + 2; break; case "C": j = j + 3; break; default: j = j + 4; }
int i = 5; int j = 8; int k = i+j; int l = 3+6;
前一部分: 0. 常量5 加載到棧 1,保存到 1號局部變量 2. 常量8 加載到棧 4 保存到2號 局部變量 5,加載1號局部變量 6, 加載2號局部變量 7 執行iadd 結果會壓入棧頂 8 棧頂元素保存到3號局部變量 至此 完成了前三行代碼 後一部分: 9.常量9 加載到棧 (3+6 已經被計算好了) 11,保存到4號局部變量 |