第五十二條钱雷、通過接口引用對象
如果有合適的接口類型存在,那么對于參數吹零、返回值罩抗、變量和域來說,就都應該使用接口類型的聲明灿椅。只有當你利用構造器創(chuàng)建某個對象的時候套蒂,才真正需要引用這個對象的類。如:
List<Subscriber> subscribers = new Vector<Subscriber>();
如果養(yǎng)成了這個習慣茫蛹,程序將更加靈活操刀。當決定更換實現的時候,只需要改變構造器中類的名稱婴洼。周圍的代碼都可以正常工作骨坑,對于這種變化并不在意。
-
如果沒有合適的接口存在柬采,完全可以用類而不是接口來引用對象欢唾。
比如:值類(String和BigInteger)。值類很少會用多個實現編寫警没,通常是final的匈辱,并且很少有對應的接口振湾。
第二種情形是:對象屬于一個框架杀迹,而框架的基本類型就是類,如果對象屬于這種基于類的框架押搪,就應該使用相關的基類(往往是抽象類)來引用這個對象树酪。
最后一種情形是:類實現了接口,但是它提供了接口中不存在的額外方法大州。
第五十三條续语、接口優(yōu)先于反射機制
-
核心反射機制(core reflection facility)
java.lang.reflect
提供了“通過程序訪問關于已裝載的類的信息”的能力。給定一個Class實例厦画,可以獲得Constructor疮茄、Method和Field實例滥朱,分別代表該Class類所表示的類的Constructor、Method和Field力试。這些對象提供了“通過程序來訪問類的成員名稱徙邻、域類型、方法簽名等信息”的能力畸裳。
而且缰犁,Constructor、Method怖糊、Field實例能夠使你通過反射機制操作它們的底層對等體:通過調用上述三項上的方法帅容,可以構造底層類的實例。調用底層類的方法伍伤,并訪問底層類中的域并徘。
反射機制reflection允許一個類使用另一個類,即使當前者被編譯時后者還不存在嚷缭。
-
反射機制的代價:
喪失了編譯時類型檢查的好處饮亏,包括異常檢查。
執(zhí)行反射訪問所需要的代碼非常笨拙和冗長阅爽。
性能損失:比普通方法要慢不少路幸。
核心反射機制最初是為了基于組建的應用創(chuàng)建工具而設計的。這類工具需要根據裝載類付翁,并且用反射功能找出它們支持哪些方法和構造器简肴。這些工具允許用戶交互式地構造出訪問這些類的應用程序,但是所產生出來的這些應用程序能夠以正確的方式訪問這些類百侧,而不是以反射的方式砰识。反射只是在設計的時候被用到。
通常佣渴,普通應用程序在運行時不應該以反射的方式訪問對象辫狼。有一些復雜的應用程序需要使用反射機制。比如:類瀏覽器辛润、對象監(jiān)視器膨处、代碼分析工具、解釋型的內嵌式系統砂竖。在RPC(遠程過程調用)系統中使用反射機制也是十分合適的真椿。
-
反射機制的好處:
對于有些程序,它們必須用到在編譯時無法獲取的類乎澄,但是在編譯時存在適當的接口或者超類突硝,通過它們可以引用這個類。以反射方式創(chuàng)建實例置济,然后通過它們的接口或者超類解恰,正常的方式訪問這些實例锋八。
Class.newInstance
方法就已經提供不帶參數的構造方法。 總結:反射機制是一種功能強大的機制护盈,對于特定的復雜系統編程任務查库,它是非常必要的,但是它也有一些缺點黄琼。如有可能樊销,就應該僅僅使用反射機制來實例化對象,而訪問對象時使用編譯時已知的某些接口或者超類脏款。
第五十四條围苫、謹慎地使用本地方法
Java Native Interface(JNI)允許Java應用調用本地方法Native Method,本地方法是指用本地程序設計語言(如C或C++)來編寫特殊的方法撤师。本地方法在本地語言中可以執(zhí)行任意的計算任務剂府,并返回到Java程序設計語言。
-
本地方法的用途:
提供了”訪問特定于平臺的機制“的能力剃盾,比如訪問注冊表和文件鎖腺占。
提供了訪問遺留代碼庫的能力,從而可以訪問遺留數據痒谴。
本地方法可以通過本地語言衰伯,編寫應用程序中注重性能的部分,以提高系統的性能积蔚。
-
使用本地方法來提高性能的方法不值得提倡:
隨著JVM實現變得越來越快意鲸。使用本地方法的缺點在于:由于本地語言不是安全的,會引發(fā)內存毀壞的錯誤尽爆;由于本地語言是與平臺相關的怎顾,使用本地方法的應用程序不再是可自由移植的;使用本地方法的程序也更加難以調試漱贱。在進入和退出本地方法的時候需要相關固定的開銷槐雾;膠合代碼難以閱讀。
第五十五條幅狮、謹慎地進行優(yōu)化
-
三條關于優(yōu)化的格言:
- 很多計算上的過失都被歸咎于效率(沒有必要達到的效率)募强。而不是任何其他的原因——甚至包括盲目地做傻事。
- 不要去計較效率上的一些小小得失彪笼,在97%的情況下钻注,不成熟的優(yōu)化才是一切問題的根源蚂且。
- 在優(yōu)化方面配猫,我們應該遵守兩條規(guī)則:
- 不要進行優(yōu)化,
- 還是不要進行優(yōu)化杏死。
優(yōu)化的弊大于利泵肄,尤其是不成熟的優(yōu)化捆交。這并不意味著,在完成程序之前就可以忽略性能問題腐巢,必須要在設計過程中考慮性能問題:努力避免那些限制性能的設計決策品追;要考慮API設計決策的性能后果。一旦謹慎地設計了程序冯丙,并且產生了一個清晰肉瓦、簡明、結構良好的實現胃惜,那么就到了考慮優(yōu)化的時候了泞莉。
第五十六條、遵守普遍接受的命名慣例
java平臺建立了一整套很好的命名慣例naming convention船殉,不嚴格地說鲫趁,這些命名慣例分為兩大類:字面的(typographical)和語法的(grammatical)。
-
字面的慣例簡要的介紹:
包的名稱應該是層次狀的利虫,用句號分割每個部分挨厚。每個部分都包括小寫字母和數字(很少),任何將在你的組織之外使用的包糠惫,其名稱都應該以你的組織的Internet域名開頭疫剃,并且頂級域名放在前面,例如:
edu.cmu
,com.sun
,gov.nsa
硼讽。標準類庫和一些可選的包慌申,其名稱以java和javax開頭,這屬于這一規(guī)則的例外理郑。用戶創(chuàng)建的包的名稱絕對不能以java和javax開頭蹄溉;包名稱的剩余部分應該包括一個或者多個描述該包的組成部分。這些描述應該比較簡短您炉,一般不超過8個字符柒爵,鼓勵使用有意義的縮寫:如
util
,awt
等赚爵。類和接口的名稱棉胀,包括枚舉和注解類型的名稱,都應該包括一個或者多個單詞冀膝,每個單詞的首字母大寫(如
Timer
和TimerTask
)唁奢;應該盡量避免縮寫。方法和域的名稱與類和接口的名稱一樣窝剖,遵循相同的字面慣例麻掸,只是第一個字母應該小寫。如果首字母縮寫組成的單詞是一個方法或者域名稱的第一個單詞赐纱,它就應該是小寫形式脊奋。
”常量域“它的名稱應該包含一個或者多個大寫的單詞熬北,中間用下劃線符號隔開。
局部變量名稱的字面慣例與成員名稱類似诚隙,只不過它也允許縮寫讶隐,單個字符和短字符序列的意義取決于上下文。
參數類型名稱通常由單個字母組成:通常是下面五種類型之一:T表示任意的類型久又;E表示集合的元素類型巫延;K和V表示映射的鍵和值類型;X表示異常地消。任何類型的序列都可以是T烈评、U、V或者T1犯建、T2讲冠、T3。
-
語法命名慣例:比字面慣例更加靈活但是有爭議适瓦。
類通常用一個名詞或者名詞短語命名竿开;
接口的命名與類類似,或者用一個已-able或者-ible結尾的形容詞來命名:
Runable
玻熙,Iterable
等執(zhí)行某個動作的方法通常用動詞或者動詞短語來命名否彩,對于返回boolean值的方法奔坟,其名稱往往以單詞”is“開頭腕巡,后面跟名詞或者名詞短語,或者任何具有形容詞功能的單詞或者短語:
isEmpty
肾请,isEnabled
等如果方法返回被調用對象的一個非boolean的函數或者屬性枚尼,通常使用名詞贴浙、名詞短語或者以動詞”get“開頭的動詞短語來命名:如
size
,hasCode
或者getTime
。轉換對象類型的方法署恍、返回不同類型的獨立對象的方法崎溃,通常稱為toType;
返回視圖的方法通常稱為asType:
asList
返回一個與被調用的對象同值的基本類型方法,通常被稱為typeValue:
intValue
;靜態(tài)工廠的常用名稱為:
valueOf
盯质、of
袁串、getInstance
、newInstance
呼巷、getType
和newType
囱修。