歡迎光臨
每天分享高質量文章

Java 中 i = i++ 問題分析

(點選上方公眾號,可快速關註)

來源:Ticmy ,

www.ticmy.com/?p=43

 

int i = 0;

i = i++;

 

結果還是0

為什麼?

 

程式的執行順序是這樣的:因為++在後面,所以先使用i,“使用”的含義就是i++這個運算式的值是0,但是並沒有做賦值操作,它在整個陳述句的最後才做賦值,也就是說在做了++操作後再賦值的,所以最終結果還是0

 

讓我們看的更清晰點:

 

int i = 0;//這個沒什麼說的

i = i++;//等效於下麵的陳述句:

 

int temp = i;//這個temp就是i++這個運算式的值

i++; //i自增

i = temp;//最終,將運算式的值賦值給i

 

這是java裡的實現,當然在其他的語言如c或是c++中可能並不是這麼處理的,每種語言都有各自的理由去做相應的處理。

 

這警示我們:不要在單個的運算式中對相同的變數賦值超過一次

 

讓我們從位元組碼層次看一看,原始碼如下:

 

public class Test {

 

    public static void main(String… args) { 

        int i = 0;

        i = i++;

        System.out.println(i);

    }

}

 

使用javac編譯後再使用javap -c Test反編譯這個類檢視它的位元組碼,如下(只摘取main方法):

 

public static void main(java.lang.String[]);

 

Code:

 

0: iconst_0

 

1: istore_1

 

2: iload_1

 

3: iinc 1, 1

 

6: istore_1

 

7: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;

 

10: iload_1

 

11: invokevirtual #3; //Method java/io/PrintStream.println:(I)V

 

14: return

 

這裡,我從第0行開始分析(分析中【】表示棧,棧的底端在左邊,頂端在右邊):

 

0:將常數0壓入棧,棧內容:【0】

 

1:將棧頂的元素彈出,也就是0,儲存到區域性變數區索引為為1(也就是變數i)的地方。棧內容:【】

 

2:將區域性變數區索引為1(也就是變數i)的值壓入棧,棧內容:【0】

 

3:將區域性變數區索引為1(也就是常量i)的值加一,此時區域性變數區索引為1的值(也就是i的值)是1。棧內容:【0】

 

6:將棧頂元素彈出,儲存到區域性變數區索引為1(也就是i)的地方,此時i又變成了0。棧內容:【】

 

7:獲取常量池中索引為2所表示的類變數,也就是System.out。棧元素:【】

 

10:將區域性變數區索引為1的值(也就是i)壓入棧。棧元素:【0】

 

11:呼叫常量池索引為3的方法,也就是System.out.println

 

14:傳回main方法

下載文章的PDF

 

http://zh.pdf24.org/

 

【關於投稿】

如果大家有原創好文投稿,請直接給公號傳送留言。

① 留言格式:
【投稿】+《 文章標題》+ 文章連結

② 示例:
【投稿】《不要自稱是程式員,我十多年的 IT 職場總結》:http://blog.jobbole.com/94148/

③ 最後請附上您的個人簡介哈~

看完本文有收穫?請轉發分享給更多人

關註「ImportNew」,提升Java技能

    贊(0)

    分享創造快樂