1 回答

TA貢獻(xiàn)1893條經(jīng)驗(yàn) 獲得超10個(gè)贊
那是因?yàn)閎 += 1.0;等價(jià)于b = (int) ((b) + (1.0));。的基本收縮轉(zhuǎn)換(JLS 5.1.3)隱藏在復(fù)合賦值操作。
JLS 15.26.2復(fù)合賦值運(yùn)算符(JLS第三版):
形式為E1 op = E2的復(fù)合賦值表達(dá)式等效于E1 =(T)(((E1)op(E2))),其中T是E1的類型,只是E1僅被評(píng)估一次。
例如,以下代碼是正確的:
short x = 3;
x += 4.6;
并導(dǎo)致x具有該值,7因?yàn)樗刃в冢?/p>
short x = 3;
x = (short)(x + 4.6);
這也解釋了為什么以下代碼會(huì)編譯:
byte b = 1;
int x = 5;
b += x; // compiles fine!
但這不是:
byte b = 1;
int x = 5;
b = b + x; // DOESN'T COMPILE!
在這種情況下,您需要顯式轉(zhuǎn)換:
byte b = 1;
int x = 5;
b = (byte) (b + x); // now it compiles fine!
值得注意的是,復(fù)合賦值中的隱式強(qiáng)制轉(zhuǎn)換是精彩書(shū)籍Java Puzzlers中的Puzzle 9:Tweedledum的主題。這是本書(shū)的摘錄(為簡(jiǎn)潔起見(jiàn),對(duì)其進(jìn)行了略作編輯):
許多程序員認(rèn)為這x += i;僅僅是的簡(jiǎn)寫x = x + i;。事實(shí)并非如此:如果結(jié)果的類型比變量的類型寬,則復(fù)合賦值運(yùn)算符將執(zhí)行無(wú)聲收窄基元轉(zhuǎn)換。
為了避免不愉快的意外,不要類型的變量使用復(fù)合賦值運(yùn)算符 byte,short或char。當(dāng)類型的變量使用復(fù)合賦值運(yùn)算符int,確保在右手側(cè)的表達(dá)式的類型不long,float或double。在類型變量上使用復(fù)合賦值運(yùn)算符時(shí)float,請(qǐng)確保右側(cè)的表達(dá)式不是type double。這些規(guī)則足以防止編譯器生成危險(xiǎn)的縮小強(qiáng)制類型轉(zhuǎn)換。
對(duì)于語(yǔ)言設(shè)計(jì)師來(lái)說(shuō),復(fù)合賦值運(yùn)算符生成不可見(jiàn)的強(qiáng)制轉(zhuǎn)換可能是一個(gè)錯(cuò)誤;變量類型比計(jì)算結(jié)果窄的復(fù)合賦值可能是非法的。
最后一段值得注意:C#在這方面要嚴(yán)格得多(請(qǐng)參見(jiàn)C#語(yǔ)言規(guī)范7.13.2復(fù)合賦值)。
添加回答
舉報(bào)