JAVA循環(huán)謎題30:循環(huán)者的愛子

字號(hào):

請(qǐng)?zhí)峁┮粋€(gè)對(duì)i的聲明,將下面的循環(huán)轉(zhuǎn)變?yōu)橐粋€(gè)無(wú)限循環(huán):
    while (i != i + 0) {
    }
    與前一個(gè)謎題不同,你必須在你的答案中不使用浮點(diǎn)數(shù)。換句話說(shuō),你不能把i聲明為double或float類型的。
    與前一個(gè)謎題一樣,這個(gè)謎題初看起來(lái)是不可能實(shí)現(xiàn)的。畢竟,一個(gè)數(shù)字總是等于它自身加上0,你被禁止使用浮點(diǎn)數(shù),因此不能使用NaN,而在整數(shù)類型中沒有NaN的等價(jià)物。那么,你能給出什么呢?
    我們必然可以得出這樣的結(jié)論,即i的類型必須是非數(shù)值類型的,并且這其中存在著解謎方案。的 + 操作符有定義的非數(shù)值類型就是String。+ 操作符被重載了:對(duì)于String類型,它執(zhí)行的不是加法而是字符串連接。如果在連接中的某個(gè)操作數(shù)具有非String的類型,那么這個(gè)操作書就會(huì)在連接之前轉(zhuǎn)換成字符串[JLS 15.18.1]。
    事實(shí)上,i可以被初始化為任何值,只要它是String類型的即可,例如:
    String i = "Buy seventeen copies of Effective Java";
    int類型的數(shù)值0被轉(zhuǎn)換成String類型的數(shù)值”0”,并且被追加到了感嘆號(hào)之后,所產(chǎn)生的字符串在用equals方法計(jì)算時(shí)就不等于最初的字符串了,這樣它們?cè)谑褂?=操作符進(jìn)行計(jì)算時(shí),當(dāng)然就不是相等的。因此,計(jì)算布爾表達(dá)式(i != i + 0)得到的值就是true,循環(huán)也就永遠(yuǎn)不會(huì)被終止了。
    總之,操作符重載是很容易令人誤解的。在本謎題中的加號(hào)看起來(lái)是表示一個(gè)加法,但是通過(guò)為變量i選擇合適的類型,即String,我們讓它執(zhí)行了字符串連接操作。甚至是因?yàn)樽兞勘幻麨閕,都使得本謎題更加容易令人誤解,因?yàn)閕通常被當(dāng)作整型變量名而被保留的。對(duì)于程序的可讀性來(lái)說(shuō),好的變量名、方法名和類名至少與好的注釋同等重要。
    對(duì)語(yǔ)言設(shè)計(jì)者的教訓(xùn)與謎題11和13中的教訓(xùn)相同。操作符重載是很容易引起混亂的,也許 + 操作符就不應(yīng)該被重載用來(lái)進(jìn)行字符串連接操作。有充分的理由證明提供一個(gè)字符串連接操作符是多么必要,但是它不應(yīng)該是 + 。