講述自增(自減)陷阱問題之前,先給大家回顧一下前置++和後置++的區別:
public class Test {
public static void main(String[] args) {
System.out.println("i++");
int i = 3;
int count = (i++) + (i++) + (i++);
//i=6
System.out.println(i);
//count=3+4+5=12
System.out.println(count);
System.out.println("++i");
int j = 3;
count = (++j) + (++j) + (++j);
//j=6
System.out.println(j);
//count=4+5+6=15
System.out.println(count);
}
}
區別總結如下:
前置++(++i):先給值自增1,然後再參與運算(先賦值再使用);
後置++(i++):先參與運算,然後再給值自增1(先使用再賦值)。
注:前置--(--i)和後置--(i--)的區別同上。
重點來了,請集中注意力,筆者在刷題時,遇到一個很靈異的事件,話不多說,上代碼,如下所示:
public class TestDemo {
public static void main(String[] args) {
int count = 0;
for (int i = 0; i < 10; i++) {
count = count++;
}
System.out.println("count的值爲:" + count);
}
}
最後輸出的count值是多少? 我相信很多人都直接會說count爲10嘛,這有什麼難的!結果是多少,編譯器告訴你!!!
驚訝嗎?count的值沒變,還是最初始的值0,並不是我們認爲的10。
福利來了,筆者下去查閱了很多資料,瞭解到Java的JVM對自增是這樣處理的:首先把count 的值(注意是值,不是引用)拷貝到一個臨時變量區,然後對 count變量加1,最後返回臨時變量區的值。
程序第一次循環時的詳細處理步驟如下:
step1:JVM把count值(其值是0)拷貝到臨時變量區;
step2:count值加1,這時候count的值是1;
step3:返回臨時變量區的值,注意這個值是0,沒修改過;
step4:返回值賦值給count,此時count值被重置成0。
注:於是第一次循環後count的值還是0,其他9次的循環也是一樣的,最終你會發現count的值始終沒有改變,仍然保持着最初的狀態。
簡而言之,可以將自增理解爲如下代碼:
public int autoIncrement(int count){
//先保存初始值
int temp =count;
//做自增操作
count = count+1;
//返回原始值
return temp;
}
那麼,“count = count++”這條語句的代碼含義則可以理解爲:
temp = count;
count = count + 1;
count = temp;
如果將語句改爲,“count = ++count”呢?修改對應代碼後:
public class TestDemo {
public static void main(String[] args) {
int count = 0;
for (int i = 0; i < 10; i++) {
count = ++count;
}
System.out.println("count的值爲:" + count);
}
}
運行結果如下:
“count = ++count”這條語句的代碼含義則可以理解爲:
//前置++嘛,先賦值再使用咯
temp = count + 1;
count = count + 1;
count = temp;
細心閱讀此題,不難發現,此代碼只是想給count自增10次,那麼如果我們將語句“count = count++”改爲“count++”,結果毋庸置疑,count的值肯定爲10,雖然語句“count = ++count”等效於“count++”,但筆者仍然推薦大家使用語句“count++”,原因很簡單,語句“count = ++count”不容易理解。
筆者查閱資料得知,C++中“count=count++”與“count++”是等效的,而在PHP中則保持着與Java相同的處理方式。
關於此類陷阱問題,代碼總結如下:
public class AutoIncrementAndAutoDecrement {
public static void main(String[] args) {
int count1 = 0;
int count2 = 0;
int count3 = 0;
int count4 = 0;
for (int i = 0; i < 10; i++) {
count1 = count1++;
count2 = ++count2;
count3++;
++count4;
}
System.out.println("表達式:count1 = count1++ ,循環結束後,count1的值爲:" + count1);
System.out.println("表達式:count2 = ++count2 ,循環結束後,count2的值爲:" + count2);
System.out.println("表達式:count3++ ,循環結束後,count3的值爲:" + count3);
System.out.println("表達式:++count4 ,循環結束後,count4的值爲:" + count4);
System.out.println();
int num1 = 10;
int num2 = 10;
int num3 = 10;
int num4 = 10;
for (int j = 0; j < 10; j++) {
num1 = num1--;
num2 = --num2;
num3--;
--num4;
}
System.out.println("表達式:num1 = num1--,循環結束後,num1的值爲:" + num1);
System.out.println("表達式:num2 = --num2,循環結束後,num2的值爲:" + num2);
System.out.println("表達式:num3--,循環結束後,num3的值爲:" + num3);
System.out.println("表達式:--num4,循環結束後,num4的值爲:" + num4);
}
}
輸出結果如下:
心得總結:
(1)自增自減操作時,直接使用count++(++count)或者count--(--count)即可;
(2)循環語句中對變量的前置++(--)和後置++(--)的輸出結果是相同的。
注:如果變量的修改涉及到表達式,那麼就要特別注意前置++(--)和後置++(--)的區別了。