讀古今文學網 > 編寫高質量代碼:改善Java程序的151個建議 > 建議7:警惕自增的陷阱 >

建議7:警惕自增的陷阱

記得大學剛開始學C語言時,老師就說:自增有兩種形式,分別是i++和++i, i++表示的是先賦值後加1,++i是先加1後賦值,這樣理解了很多年也沒出現問題,直到遇到如下代碼,我才懷疑我的理解是不是錯了:


public class Client{

public static void main(Stringargs){

int count=0;

for(int i=0;i<10;i++){

count=count++;

}

System.out.println("count="+count);

}

}


這個程序輸出的count等於幾?是count自加10次嗎?答案等於10?可以非常肯定地告訴你,答案錯誤!運行結果是count等於0。為什麼呢?

count++是一個表達式,是有返回值的,它的返回值就是count自加前的值,Java對自加是這樣處理的:首先把count的值(注意是值,不是引用)拷貝到一個臨時變量區,然後對count變量加1,最後返回臨時變量區的值。程序第一次循環時的詳細處理步驟如下:

步驟1 JVM把count值(其值是0)拷貝到臨時變量區。

步驟2 count值加1,這時候count的值是1。

步驟3 返回臨時變量區的值,注意這個值是0,沒修改過。

步驟4 返回值賦值給count,此時count值被重置成0。

"count=count++"這條語句可以按照如下代碼來理解:


public static int mockAdd(int count){


//先保存初始值


int temp=count;


//做自增操作


count=count+1;


//返回原始值


return temp;

}


於是第一次循環後count的值還是0,其他9次的循環也是一樣的,最終你會發現count的值始終沒有改變,仍然保持著最初的狀態。

此例中代碼作者的本意是希望count自增,所以想當然地認為賦值給自身就成了,不曾想掉到Java自增的陷阱中了。解決方法很簡單,只要把"count=count++"修改為"count++"即可。該問題在不同的語言環境有不同的實現:C++中"count=count++"與"count++"是等效的,而在PHP中則保持著與Java相同的處理方式。每種語言對自增的實現方式各不同,讀者有興趣可以多找幾種語言測試一下,思考一下原理。

下次如果看到某人T恤上印著"i=i++",千萬不要鄙視他,記住,能夠以不同的語言解釋清楚這句話的人絕對不簡單,應該表現出「如滔滔江水」般的敬仰,心理默念著「高人,絕世高人哪」。