我們接下來討論一下Java語言的細(xì)節(jié),包括局部變量的處理,庫的使用,以及兩種不是語言本身提供的機(jī)制的使用等等一些大家平時(shí)可能忽略的問題。
Item 29:將局部變量的作用域最小化
和C語言要求局部變量必須被生命在代碼的開始處相比,Java程序設(shè)計(jì)語言寬松得多,它允許你在代碼的任何位置聲明。要想使一個(gè)局部變量的作用域最小化,最高小的技術(shù)是在第一次需要使用它的地方聲明,變量的作用域是從聲明它的地方開始到這個(gè)聲明做在的代碼塊的結(jié)束位止,如果我們把變量的聲明和代碼的使用位置分開的過大,那么對(duì)于讀這段代碼的人來說,是很不幸的。
我們幾乎都是在一個(gè)局部變量聲明的地方同時(shí)給它初始化,注意這是很重要的,甚至有時(shí)候,如果我們的初始化應(yīng)該推遲到下一個(gè)代碼的位置,我們同時(shí)應(yīng)該把聲明也往后延遲。這條規(guī)則唯一的例外是try-catch這個(gè)語句,因?yàn)槿绻粋€(gè)變量被方法初始化,那么這個(gè)方法很有可能拋出一個(gè)異常,那我們最常用的方法就是把它置于try塊的內(nèi)部去進(jìn)行初始化。由此我們可以得出,for循環(huán)優(yōu)于while循環(huán),我們?cè)谀苁褂胒or循環(huán)的地方盡量使用for而不使用while,因?yàn)閒or循環(huán)是完全獨(dú)立的,所以重用循環(huán)變量名字不會(huì)有任何傷害。
最后我們要記住的是盡量把我們的函數(shù)寫的小而集中,這樣才能真正組做到”最小化局部變量的作用域”這一要旨。
Item 30:了解和使用庫
使用標(biāo)準(zhǔn)庫,我們可以充分利用編寫這些庫的Java專家的知識(shí),以及在你之前其他人的使用經(jīng)驗(yàn),這就是所謂站在巨人的肩膀上看世界吧~
在每一個(gè)Java平臺(tái)的發(fā)行版本里面,都會(huì)有許多新的包的加入,和這些更新保持一直是值得的,比如說我們J2ME的開發(fā),在MIDP 1.0的時(shí)代,我們要寫個(gè)Game還要自己動(dòng)手寫工具類,現(xiàn)在MIDP2.0推出之后,大多數(shù)寫游戲的人都覺得方便了很多,因?yàn)樵谶@個(gè)版本里面加入了游戲包,為我們的開發(fā)節(jié)省了大量的人力物力。
Item 31:如果想要知道精確的答案,就要避免使用double和float
對(duì)于金融行業(yè)來說,對(duì)數(shù)據(jù)的嚴(yán)整性要求是很高的,不容半點(diǎn)馬虎,那大家都知道再我們的Java語言里面有兩個(gè)浮點(diǎn)數(shù)類型的變量float和double,可能大家會(huì)認(rèn)為他們的精度對(duì)于金融行業(yè)這樣對(duì)數(shù)字敏感的行業(yè)來說,已經(jīng)夠用了,但是在開發(fā)當(dāng)中,我們要盡量少使用double和float,因?yàn)樽屗麄兙_的表達(dá)0.1是不可能的。那我們?nèi)绾谓鉀Q這個(gè)問題呢,答案是使用BigDecimal,int或者long進(jìn)行貨幣計(jì)算。在這里對(duì)大家的忠告是:對(duì)于商務(wù)運(yùn)算,我們盡量使用BigDecimal,對(duì)于性能要求較高的地方,我們有能力自己處理十進(jìn)制的小數(shù)點(diǎn),數(shù)值不太大的時(shí)候,我們可以使用int或者long,根據(jù)自己的需要來判定具體使用哪一個(gè),如果范圍超過了18位數(shù),那我們必須使用BigDecimal。
Item 32:如果其他類型更適合,則盡量避免使用字符串
在偶看到這條建議之前,我就很喜歡用字符串,不管在什么場合下,先String了再說,但是實(shí)際上很多情況下,我們要根據(jù)實(shí)際情況來判定到底使用什么類型,而且字符串不適合替代枚舉類型,類型安全枚舉類型和int值都比字符串更適合用來表示枚舉類型的常量。字符串也不適合替代聚集類型,有一個(gè)更好的方法就是簡單的寫一個(gè)類來描述這個(gè)數(shù)據(jù)集,通常是一個(gè)私有的靜態(tài)成員類最好。字符串也不適合代替能力表,總而言之,如果可以適合更加適合的數(shù)據(jù)類型,或者可以編寫更加適當(dāng)?shù)臄?shù)據(jù)類型,那么應(yīng)該避免使用字符串來表示對(duì)象。
Item 33:了解字符串的連接功能
我們經(jīng)常在使用System.out.println()的時(shí)候,往括號(hào)里寫一串用“+”連接起來的字符串,這是我們最常見的,但是這個(gè)方法并不適合規(guī)模較大的情形,為連接N個(gè)字符串而重復(fù)地使用字符串連接操作符,要求N的平方級(jí)的時(shí)間,這是因?yàn)樽址欠强勺兊模@就導(dǎo)致了在字符串進(jìn)行連接的時(shí)候,前后兩者都要拷貝,這個(gè)時(shí)候我們就提倡使用StingBuffer替代String。
Item 34:通過接口引用對(duì)象
通俗的說就是盡量優(yōu)先使用接口而不是類來引用對(duì)象,如果有合適的接口存在那么對(duì)使用參數(shù),返回值,變量域都應(yīng)該使用接口類型養(yǎng)成使用接口作為對(duì)象的習(xí)慣,會(huì)使程序變得更加靈活。
如果沒有合適的接口,那么,用類而不是接口來引用一個(gè)對(duì)象,是完全合適的。
Item 35:接口優(yōu)先于映像機(jī)制
java.lang.relect提供了“通過程序來訪問關(guān)于已裝載的類的信息”,由此,我們可以通過一個(gè)給定的Class實(shí)例,獲得Constructor,Method和Field實(shí)例。
映像機(jī)制允許一個(gè)類使用另一個(gè)類,即使當(dāng)前編譯的時(shí)候后者還不存在,但是這種能力也要付出代價(jià):
我們損失了了編譯時(shí)類型檢查的好處,而且要求執(zhí)行映像訪問的代碼非常笨拙和冗長,并且在性能上大大損失。
通常,普通應(yīng)用在運(yùn)行時(shí)刻不應(yīng)以映像方式訪問對(duì)象。
Item 36:謹(jǐn)慎的使用本地方法
JNI允許Java應(yīng)用程序調(diào)用本地方法,所謂本地方法是指用本地程序設(shè)計(jì)語言(如C,C++)來編寫的特殊方法,本地方法可以在本地語言執(zhí)行任何計(jì)算任務(wù),然后返回到Java程序設(shè)計(jì)語言中。但是隨著JDK1.3及后續(xù)版本的推出這種通過使用本地方法來提高性能的方法已不值得提倡,因?yàn)楝F(xiàn)在的JVM越來越快了,而且使用本地方法有一些嚴(yán)重的缺點(diǎn),比如使Java原本引以為傲的安全性蕩然無存,總之在使用本地方法的時(shí)候要三思。
Item 37:謹(jǐn)慎使用優(yōu)化
不要因?yàn)樾阅芏鵂奚侠淼拇a結(jié)構(gòu),努力編寫好的程序而不是快的程序,但是避免那些限制性能的設(shè)計(jì)決定,同時(shí)考慮自己設(shè)計(jì)的API決定的性能后果,為了獲得更好的性能而對(duì)API進(jìn)行修改這也是一個(gè)非常不好的想法,通常我們?cè)谧鰞?yōu)化之后,都應(yīng)該對(duì)優(yōu)化的程度進(jìn)行一些測量。
Item 38:遵守普遍接受的命名慣例
Java有一套比較完善的命名慣例機(jī)制,大部分包含在《The Java Language Specification》,嚴(yán)格得講這些慣例分成兩類,字面的和語法的。
字面涉及包,類,接口,方法和域,語法的命名慣例比較靈活,所以爭議更大,字面慣例是非常直接和明確的,而語法慣例則相對(duì)復(fù)雜,也很松散。但是有一個(gè)公認(rèn)的做法是:“如果長期養(yǎng)成的習(xí)慣用法與此不同的話,請(qǐng)不要盲目遵從.