**
原址:先看4個題目:
①int i = 0;
i = i++;
②int i = 0;
i = ++i;
③int i = 0;
int j = 0;
j = i++ + i++;
④ int i = 0;
int j = 0;
j = i++ + i++ + i++;
每道題裡的i和j都是多少?
用myeclipse測試,結果分別是①i = 0,②i = 1,③i = 2,j = 1,④i = 3,j = 3。
i++和++i的問題,困擾很多人。網上、書上的解釋各種各樣。現在通過分析位元組碼,來確定這兩條語句究竟是怎樣執行的。
先給出今天要用到的位元組碼的含義
bytecode
stack
before->after
description
iconst_0
->0
loads the int value 0 onto the stack
istore_1
value->
store int value into variable 1
istore_2
value->
store int value into variable 2
iinc
no change
increment local variable #index by signed byte const
iload_1
->value
loads an int value from variable 1
iadd
value 1,value 2->result
adds 2 ints together
說明兩點需要注意的地方:
①iinc操作是有引數的,但是在此忽略,簡寫為iinc,此操作對應於自加操作,並且該操作不對stack有任何改變;
②iadd操作過後只在stack中保留結果result。
接下來是四段程式主要的位元組碼:
①iconst_0 ②iconst_0 ③iconst_0 ④iconst_0
istore_1 istore_1 istore_1 istore_1
iload_1 iinc 1,1 iconst_0 iconst_0
iinc 1,1 iload_1 istore_2 istore_2
istore_1 istore_1 iload_1 iload_1
iinc 1,1 iinc 1,1
iload_1 iload_1
iinc 1,1 iinc 1,1
iadd iadd
istore_2 iload_1
iinc 1,1
iadd
istore_2
現在解釋①。第一步在stack中存入乙個int常量0;第二步把它賦值給第乙個變數,即我們的i;第三步把第乙個變數i的值存入到stack中;第四步在i自身的空間進行自加,而第三步存入到stack中的值沒有變;第五步把第三步存入到stack中的值再賦值給第乙個變數i。也就是說,i真的是進行自加了,但是被自己原來的值覆蓋掉了。從這裡我們可以看出,自加操作比賦值操作的優先順序高。
再看②。和①比較起來,區別就在於,++i是先進行自加,然後把自加後的值存入到stack中,所以最後賦值給i的是1,不是0。
③呢?首先,③比前兩個多了乙個變數,但這不是重點。往下看,把第乙個變數i的值(0)存入到stack中,i自加,再第乙個變數i的值(1)存入到stack中,再自加。此時stack中有兩個值了,0和1,進行加操作後的結果是1,然後賦值給第二個變數j。這裡顛覆了我們以前被告知的,加的運算優先順序比自加高。這就是困擾我們的,其實,只要把值讀入到stack中,接下來就進行自加,只有得到了兩個引數,才進行加操作。
來看④。前面都和③一樣,只到進行了第一次加操作,得到的結果(1)儲存在stack中,沒有賦值給j,然後再次讀入i的值(2)到stack,i自加,得到加操作的兩個引數,1和2,進行第二次加操作的結果是3,賦值給j。
到此,問題都解決了。
位元組碼指令分析 i 和 i
最近在學jvm,碰到一道分析題,用位元組碼指令分析 i 和 i 的區別,相信大家對 i 和 i 的區別應該非常熟悉,但是具體為什麼會這樣可能還是一知半解,這篇分享和大家共同解惑。非常簡單,這裡就只分析question02了,下面的內容如果不熟悉區域性變數表和運算元棧的可能不太容易理解。public ...
java 的 i 和 i 的區別
我知道網上有很多這樣的文章了,在這我只是想記錄一下,總結一下,就當備忘錄吧。一 什麼區別?1 i 先運算再加一,i先加一再運算 2 i 有中間變數,i 沒有,理論上 i 相對執行快點 二 裡有詳細的解釋 總結 i 最終去相加的都是中間變數 temp,請看例子 author tingliu creat...
java執行linux命令獲取MAC和ip位址
獲取linux ubuntu網絡卡的mac位址 public static string getmacaddressbylinux try catch exception e return mac 獲取linux ubuntu eth0 內網ip位址 public static string get...