位元組碼中的常用指令
阿新 • • 發佈:2020-10-16
一道面試題,問最後輸出多少?
public static void main(String[] args) {
int a = 10;
a = a++; // 輸出10
//a = ++a; // 輸出11
System.out.println(a);
}
上述程式碼對應的位元組碼指令
一個main方法對應虛擬機器棧的一個棧幀,下面所說的運算元棧就是棧幀中的運算元棧。對變數進行數學運算或者賦值等操作都要把運算元彈出棧。
使用a = a++ 後位元組碼的指令
- bipush : 將10 壓入運算元棧
- istore_1:將10出棧,並賦值給區域性變量表中下標為1(下標為0的是 this 變數)的變數a,完成賦值語句。
- iload_1:因為要對a進行賦值操作,把10壓入運算元棧。
- iinc 1 by 1:但是在上一步最終完成賦值之前,要對a進行++操作,所以直接將區域性變量表中下標為1即變數a進行加1,此時a = 11。
- istore_1:將運算元的的數彈出並賦值給a,a 又變成了10。所以最後輸出10
使用a = ++a後的位元組碼指令
- bipush 10: 將10壓入運算元棧
- istore_1:將10出棧,並賦值給區域性變量表中下標為1的變數a,完成賦值語句。
- iinc 1 by 1:因為這裡是先自加再賦值,所以將a + 1變成11。
- iload_1:現在執行賦值操作,所以先讓11入運算元棧。
- istore_1:讓11出棧,給a賦值。最終a = 11。
常用指令總結
-
bipush: 壓棧
-
iload_x:將區域性變量表中下標為x壓入棧
-
istore_x:將棧定資料彈出,賦值給區域性變數中下標為x的變數
-
iadd:將棧頂兩個元素彈出,進行相加操作
-
isub:將棧頂兩個元素彈出,進行相減操作
-
invokespecial:執行特殊方法,即不需要多型的方法。
例如:private方法、構造方法
-
invokevirtual:呼叫方法
-
invokestatic:執行靜態方法
.....