java中i=i++問題分析

int i = 0;java

i = i++;c++

結果仍是0
爲何?

程序的執行順序是這樣的:由於++在後面,因此先使用i,「使用」的含義就是i++這個表達式的值是0,可是並無作賦值操做,它在整個語句的最後才作賦值,也就是說在作了++操做後再賦值的,因此最終結果仍是0spa

讓咱們看的更清晰點:code

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

i = i++;//等效於下面的語句:ci

 

int temp = i;//這個temp就是i++這個表達式的值get

i++; //i自增源碼

i = temp;//最終,將表達式的值賦值給iio

這是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方法

相關文章
相關標籤/搜索