JAVA循環(huán)謎題25:無情的增量操作

字號:

下面的程序?qū)σ粋€變量重復地進行增量操作,然后打印它的值。那么這個值是什么呢?
    public class Increment {
     public static void main(String[] args) {
     int j = 0;
     for (int i = 0; i < 100; i++)
     j = j++;
     System.out.println(j);
     }
    }
    乍一看,這個程序可能會打印100。畢竟,它對j做了100次增量操作??赡軙钅愀械接行┱痼@,它打印的不是100而是0。所有的增量操作都無影無蹤了,為什么?
    就像本謎題的題目所暗示的,問題出在了執(zhí)行增量操作的語句上:
    j = j++;
    大概該語句的作者是想讓它執(zhí)行對j的值加1的操作,也就是表達式j(luò)++所做的操作。遺憾的是,作者大咧咧地將這個表達式的值有賦回給了j。
    當++操作符被置于一個變量值之后時,其作用就是一個后綴增量操作符(postfix increment operator)[JLS 15.14.2]:表達式j(luò)++的值等于j在執(zhí)行增量操作之前的初始值。因此,前面提到的賦值語句首先保存j的值,然后將j設(shè)置為其值加1,最后將j復位到它的初始值。換句話說,這個賦值操作等價于下面的語句序列:
    int tmp = j;
    j = j + 1;
    j = tmp?;
    程序重復該過程100次,之后j的值還是等于它在循環(huán)開始之前的值,即0。
    訂正該程序非常簡單,只需從循環(huán)中移除無關(guān)的賦值操作,只留下:
    for (int i = 0; i < 100; i++)
     j++;
    經(jīng)過這樣的修改,程序就可以打印出我們所期望的100了。
    這與謎題7中的教訓相同:不要在單個的表達式中對相同的變量賦值超過一次。對相同的變量進行多次賦值的表達式會產(chǎn)生混淆,并且很少能夠產(chǎn)生你希望的行為。