3: Controlling Program Flow(控制程序流程)

使用Java運(yùn)算符
幾乎所有的運(yùn)算符都只能作用于primitive。但是‘=’,‘==’,以及‘!=’是例外,它們可以作用于任何對(duì)象(由此也是對(duì)象方面一個(gè)很讓人頭暈的問(wèn)題。)此外,String類(lèi)也支持‘+’和‘+=’。
優(yōu)先級(jí)
賦值

primitive賦值的時(shí)候,是將內(nèi)容從一個(gè)地方直接拷貝到另一個(gè)地方。
操控對(duì)象就得通過(guò)reference來(lái)進(jìn)行操作。當(dāng)你“在對(duì)象之間”進(jìn)行賦值得時(shí)候,實(shí)際上你是在拷貝它得reference。
方法調(diào)用期間的aliasing
數(shù)學(xué)運(yùn)算符
正則表達(dá)式(Regular expressions)
單元的加號(hào)和減號(hào)運(yùn)算符
自動(dòng)遞增與遞減
對(duì)于前置遞增和前置遞減,(也就是++a和--a),操作過(guò)程是會(huì)先計(jì)算再返回。對(duì)于后置遞增和后置遞減,(也就是a++和a--),操作步驟是先返回再計(jì)算。
關(guān)系運(yùn)算符
測(cè)試對(duì)象的相等性

==和!=比較的是對(duì)象的reference。要想比較這兩個(gè)對(duì)象的實(shí)際內(nèi)容,必須使用每個(gè)類(lèi)都有的,專門(mén)的equals()方法(primitives沒(méi)有,因?yàn)?=和!=就用得很好)。
equals()的缺省行為是比較reference。
邏輯運(yùn)算符
短接
位運(yùn)算符

位運(yùn)算符可以與=連起來(lái)用,以表示同時(shí)進(jìn)行計(jì)算和賦值:&=,|=和^=都是合法的。(至于~,它既然是一個(gè)單元運(yùn)算符,也就不需要同=綁在一起了。)
Boolean類(lèi)型會(huì)被當(dāng)作只有一位的值,所以它多少有點(diǎn)不同。你可以進(jìn)行與,或,以及異或運(yùn)算,但是不能進(jìn)行非運(yùn)算(可能是為了防止同邏輯非相混淆)。對(duì)于boolean,位運(yùn)算用邏輯運(yùn)算的在功能上是相同的,只是它沒(méi)有短接。此外boolean的位運(yùn)算里有一個(gè)邏輯運(yùn)算所沒(méi)有的異或。
移位運(yùn)算符
它只能用于整數(shù)型的primitive數(shù)據(jù)。
三元if-else運(yùn)算符
逗號(hào)運(yùn)算符
Java里面,唯一一個(gè)把逗號(hào)當(dāng)運(yùn)算符用的地方是for循環(huán)。
String的+運(yùn)算符
常見(jiàn)的使用運(yùn)算符方面的錯(cuò)誤
類(lèi)型轉(zhuǎn)換運(yùn)算符

碰到所謂的narrowing conversion的時(shí)候(也就是說(shuō),當(dāng)你將一個(gè)能保存較多信息的數(shù)據(jù)類(lèi)型,轉(zhuǎn)換成一個(gè)保存不了這么多信息的數(shù)據(jù)類(lèi)型時(shí)),它會(huì)產(chǎn)生一個(gè)異常。編譯器會(huì)強(qiáng)制你明確地進(jìn)行轉(zhuǎn)換,實(shí)際上它的潛臺(tái)詞是“這么做可能很危險(xiǎn)——如果你一定要做,那么請(qǐng)明確地告訴我”。
對(duì)于widening conversion,就不必進(jìn)行顯式轉(zhuǎn)換了,因?yàn)樾骂?lèi)型可以存儲(chǔ)比舊類(lèi)型更多的信息,所以什么都丟不了。
Java允許你對(duì)除boolean之外的其它primitive類(lèi)型的數(shù)據(jù)進(jìn)行任意的轉(zhuǎn)換,而boolean則根本不能轉(zhuǎn)換。
類(lèi)是不允許轉(zhuǎn)換的。要讓他們相互轉(zhuǎn)換,必須要有特殊的方法。(String是一個(gè)特例。此外,所有對(duì)象都可以在它的類(lèi)系(family of types)里面上下傳遞。)
常量(Literals)
C,C++或者Java里面都沒(méi)有兩進(jìn)制常量值的表示方法。
跟在常量值后面的那個(gè)數(shù)字表明了它的類(lèi)型。大寫(xiě)或者小寫(xiě)的L表示long,大寫(xiě)或者小寫(xiě)的F表示float,而大寫(xiě)或者小寫(xiě)的D表示double。
編譯器通常會(huì)把用指數(shù)表示的數(shù)字當(dāng)成double,所以在給float賦值如果沒(méi)有后綴的f的話,它就會(huì)給你一個(gè)錯(cuò)誤信息,告訴你你必須將double轉(zhuǎn)換成float。
提升
Java沒(méi)有“sizeof”
重訪優(yōu)先級(jí)
Ulcer Addicts Really Like C A lot.

Mnemonic

Operator type

Operators

Ulcer

Unary

+ - ++--

Addicts

Arithmetic(and shift)

* / % + - << >>

Really

Relational

> < >= <= == !=

Like

Logical(and bitwise)

&& || & | ^

C

Conditional(ternary)

A > B? X: Y

A Lot

Assignment

=(and compound assignment like *=)

運(yùn)算符的總結(jié)
boolean的限制性是很強(qiáng)的。你只能賦給它true和false這兩個(gè)值,而且只能測(cè)試它的真或假,你不能把boolean值加起來(lái),或者進(jìn)行其它什么操作。
進(jìn)行數(shù)學(xué)運(yùn)算的時(shí)候,char,byte,以及short,都會(huì)先進(jìn)行提升,而運(yùn)算結(jié)果也是int,因此如果想把它賦還給原先那個(gè)變量的話,舊必須明確地進(jìn)行類(lèi)型轉(zhuǎn)換(屬于會(huì)丟失信息的narrowing conversion)。

執(zhí)行控制
true和false
if-else
return
循環(huán)語(yǔ)句
do-while
while與do-while的唯一區(qū)別就是,即使第一次判斷的結(jié)果是false,do-while的statement也會(huì)至少運(yùn)行一次。
for
for循環(huán)通常被用于“計(jì)數(shù)”的任務(wù)。
你可以在for語(yǔ)句里定義多個(gè)變量,但必須是相同類(lèi)型的。
只有for語(yǔ)句才有在“控制表達(dá)式”里定義變量的能力。千萬(wàn)別在其它選擇語(yǔ)句或循環(huán)語(yǔ)句里這么做。
逗號(hào)運(yùn)算符
break和continue

break會(huì)忽略尚未執(zhí)行的循環(huán)代碼,并且退出循環(huán)。
continue會(huì)跳過(guò)尚未執(zhí)行的代碼,中斷本次循環(huán),再進(jìn)入下一周期的循環(huán)。
臭名昭著的“goto”
在Java里,唯一能放標(biāo)簽的地方,就是在循環(huán)語(yǔ)句的外面。而且必須直接放——循環(huán)語(yǔ)句和標(biāo)簽之間不能有任何東西。而這么做的唯一理由就是,你會(huì)嵌套多層循環(huán)或選擇。因?yàn)橥ǔG闆r下break和continue關(guān)鍵詞只會(huì)中斷當(dāng)前循環(huán),而用了標(biāo)簽之后,它就會(huì)退到label所在的地方。
1. 普通的continue會(huì)退到內(nèi)部循環(huán)的最開(kāi)始,然后繼續(xù)執(zhí)行內(nèi)部循環(huán)。
2. 帶標(biāo)簽的continue會(huì)跳轉(zhuǎn)到標(biāo)簽,并且重新進(jìn)入直接跟在標(biāo)簽后面的循環(huán)。
3. break會(huì)從循環(huán)的“底部溜出去”。
4. 帶標(biāo)簽的break會(huì)從由這個(gè)標(biāo)簽標(biāo)識(shí)的循環(huán)的“底部溜出去”。
在Java里,能讓你使用標(biāo)簽的唯一理由就是,在嵌套循環(huán)的同時(shí)還要用break和continue退出多層循環(huán)。
switch
在case語(yǔ)句里,單引號(hào)括起來(lái)的字符在用于比較的時(shí)候,會(huì)返回整數(shù)值。
計(jì)算細(xì)節(jié)
將float或double轉(zhuǎn)換成整數(shù)的時(shí)候,它總是將其后面的小數(shù)截去。
Math.random()會(huì)生成0.0,或者用數(shù)學(xué)術(shù)語(yǔ),它的值域是[0,1)。

總結(jié)

練習(xí)

「讀書(shū)筆記」Thinking in Java 3rd Edition - 4: Initialization & Cleanup