《Effective Java》

經(jīng)典重讀——亞馬遜鏈接


筆記鏈接


導(dǎo)圖:

Effective Java overview.png

筆記文本:

Effective Java
1 第2章 創(chuàng)建和銷毀對象
1.1 1. 考慮用靜態(tài)工廠方法代替構(gòu)造器
1.1.1 優(yōu)點
1.1.1.1 優(yōu)勢一:有名稱
1.1.1.2 優(yōu)勢二:不必在每次調(diào)用它們的時候都創(chuàng)建一個新對象
1.1.1.3 優(yōu)勢三:可以返回原返回類型的任何子類型的對象
1.1.1.4 優(yōu)勢四:在創(chuàng)建參數(shù)化類型實例時淀衣,它們使代碼變得更簡潔
1.1.2 缺點
1.1.2.1 類如果不含有公有的或者受保護(hù)的構(gòu)造器,就不能被子類化
1.1.2.2 它們與其他靜態(tài)方法實際上沒有任何區(qū)別
1.2 2. 遇到多個構(gòu)造器參數(shù)時要考慮用構(gòu)建器
1.2.1 Builder
1.2.2 與構(gòu)造器相比的略微優(yōu)勢在于:builder可以有多個可變參數(shù)
1.2.3 雖然創(chuàng)建builder的開銷在實踐中可能不那么明顯召调,但是在某些十分注重性能的情況下膨桥,可能就成問題
1.2.4 builder比重疊構(gòu)造器更冗長蛮浑,因此只在很多參數(shù)時才使用
1.3 3. 用私有構(gòu)造器或者枚舉類型強(qiáng)化Singleton屬性
1.3.1 單元素的枚舉類型已經(jīng)成為實現(xiàn)Singleton的最佳方法
1.4 4. 通過私有構(gòu)造器強(qiáng)化不可實例化的能力
1.4.1 弊端:使得其不能被子類化
1.5 5. 避免創(chuàng)建不必要的對象
1.5.1 對于同時提供了靜態(tài)工廠方法和構(gòu)造器的不可變類,通持幌可以使用靜態(tài)工廠方法而不是構(gòu)造器沮稚,以避免創(chuàng)建不必要的對象
1.5.2 除了重用不可變的對象之外,也可以重用那些已知不會被修改的可變對象
1.5.3 要優(yōu)先使用基本類型而不是裝箱基本類型册舞,要當(dāng)心無意識的自動裝箱
1.5.4 自己維護(hù)對象池只在對象非常重量級時才顯得必要蕴掏,比如數(shù)據(jù)庫連接池,線程池
1.6 6. 消除過期的對象引用
1.6.1 一旦對象引用已經(jīng)過期调鲸,只需清空這些引用即可
1.6.2 緩存導(dǎo)致的內(nèi)存泄露
1.6.2.1 一種是確認(rèn)在緩存之外存在對某幾個項的鍵的引用盛杰,該項就有意義 ——可以用WeakHashMap代表緩存
1.6.2.2 針對“緩存項生命周期是否有意義”難以確認(rèn)的情況 ——緩存應(yīng)該時不時地清除掉沒用的項。這項清除工作可以由一個后臺線程來完成藐石,或者也可以在給緩存添加新條目時順便清理(LinkedHashMap類利用它的removeEldestEntry方法可以很容易實現(xiàn))
1.6.2.3 第三種引發(fā)來源是:監(jiān)聽器和其他回調(diào)即供。 確保回調(diào)立即被當(dāng)做垃圾回收的最佳方法是只保存它們的弱引用 weak reference
1.7 7. 避免使用finalizer方法
1.7.1 通常是不可預(yù)測的
1.7.1.1 一個對象從不可用開始于微,到它的終結(jié)方法被執(zhí)行逗嫡,這段時間是任意長的
1.7.2 使用它有一個非常嚴(yán)重的性能損失
1.7.3 顯示的終止方法通常與try-finally結(jié)合使用,以確保及時終止
1.7.4 用途:充當(dāng)安全網(wǎng)株依、本地對等體
1.7.5 結(jié)論:不應(yīng)該依賴終結(jié)方法來更新重要的持久狀態(tài)
1.7.6 結(jié)論:除非是作為安全網(wǎng)祸穷,或者是為了終止非關(guān)鍵的本地資源,否則不要使用
2 第3章 對所有對象都通用的方法
2.1 8. 覆蓋equals時請遵守通用約定
2.1.1 建議:能不覆蓋就不要覆蓋
2.1.2 不用覆蓋的情形
2.1.2.1 類的每個實例本質(zhì)上都是唯一的
2.1.2.2 不關(guān)心類是否提供了“邏輯相等”
2.1.2.3 超類已經(jīng)覆蓋了equals勺三,從超類繼承過來的行為對于子類也是合適的
2.1.2.4 類是私有的或是包級私有的雷滚,可以確定它的equals方法永遠(yuǎn)不會被調(diào)用
2.1.3 覆蓋的約定
2.1.3.1 自反性
2.1.3.2 對稱性
2.1.3.3 傳遞性
2.1.3.4 一致性
2.1.3.5 非空性
2.1.3.5.1 對于任何非null的引用值,x.equals(null)必須返回false
2.1.4 訣竅
2.1.4.1 使用== 檢查參數(shù)是否為這個對象的引用
2.1.4.2 使用instanceof檢查 參數(shù)是否為正確的類型
2.1.4.3 把參數(shù)轉(zhuǎn)換為正確的類型
2.1.4.4 對于該類中的每個關(guān)鍵域吗坚,檢查參數(shù)中的域是否與該對象中對應(yīng)的域相匹配
2.1.4.5 是否滿足:對稱祈远、傳遞、一致
2.1.4.6 覆蓋equals時總要覆蓋hashCode
2.1.4.7 不要企圖讓equals方法過于智能
2.1.4.8 不要將equals聲明中的Object對象替換為其他類型
2.2 9. 覆蓋 equals時總要覆蓋 hashCode
2.2.1 最佳實踐:
2.2.1.1 @Override public int hashCode(){ int result = 17; result = 31 * result + areaCode; result = 31 * result + prefix; result = 31 * result + lineNumber; }
2.3 10. 總要覆蓋 toString
2.3.1 toString方法應(yīng)該返回對象中包含的所有值得關(guān)注的信息
2.4 11. 謹(jǐn)慎地覆蓋clone
2.4.1 通則:永遠(yuǎn)不要讓客戶去做任何類庫能夠替客戶完成的事情
2.4.2 最好提供某些其他途徑來代替對象拷貝商源,或者干脆不提供這樣的功能
2.4.3 另一個實現(xiàn)對象拷貝的好方法是提供一個拷貝構(gòu)造器或拷貝工廠
2.4.4 由于它有這么多缺點车份,有些專家級的程序員干脆從來不去覆蓋clone方法,也從來不去調(diào)用它牡彻,除非拷貝數(shù)組
2.5 12. 考慮實現(xiàn)comparable接口
2.5.1 compareTo不但允許進(jìn)行簡單的等同性比較扫沼,而且允許執(zhí)行順序比較
2.5.2 如果你在編寫一個值類,它具有非常明顯的內(nèi)在排序關(guān)系庄吼,比如按字母順序缎除、按數(shù)值順序或者按年代順序,那你就應(yīng)該堅決考慮實現(xiàn)這個接口
2.5.3 如果一個類有多個關(guān)鍵域总寻,那么你必須從最關(guān)鍵的域開始器罐,逐步進(jìn)行到所有的重要域
3 第4章 類和接口
3.1 13. 使類和成員的可訪問性最小化
3.1.1 信息隱藏 或 封裝
3.1.2 盡可能地使每個類或者成員不被外界訪問
3.1.3 有一條規(guī)則限制了降低方法的可訪問性能力:如果方法覆蓋了超類中的一個方法,子類中的訪問級別就不允許低于超類中的訪問級別
3.1.4 注意:長度非零的數(shù)組總是可變的渐行,所以轰坊,類具有公有的靜態(tài)final數(shù)組域或者返回這種域的訪問方法總是會出錯
3.2 14. 在公有類中使用訪問方法而非公有域
3.2.1 如果類可以在它所在的包的外部進(jìn)行訪問铸董,就提供訪問方法
3.2.2 如果類是包級私有的,或者是私有的嵌套類肴沫,直接暴露它的數(shù)據(jù)域并沒有本質(zhì)錯誤
3.2.3 Java類庫的反面典型:Point和Dimension粟害,暴露dimension類的內(nèi)部數(shù)據(jù)造成了嚴(yán)重的性能問題,而且這個問題依然存在
3.3 15. 使可變性最小化
3.3.1 理由:比可變類更加易于設(shè)計颤芬、實現(xiàn)和使用我磁。它們不容易出錯,且更加安全
3.3.2 使類成為不可變需要遵循五條規(guī)則
3.3.2.1 1 不要提供任何會修改對象狀態(tài)的方法
3.3.2.2 2 保證類不會被擴(kuò)展
3.3.2.3 使所有的域都是final的
3.3.2.4 使所有的域都成為私有的
3.3.2.5 確保對于任何可變組件的互斥訪問
3.3.3 不可變對象的優(yōu)勢
3.3.3.1 不可變對象本質(zhì)上是線程安全的驻襟,它們不要求同步
3.3.3.2 不僅可以共享不可變對象夺艰,甚至可以共享它們的內(nèi)部信息
3.3.3.3 不可變對象為其他對象提供了大量的構(gòu)件
3.3.3.4 不可變對象真正唯一的缺點是,對于每個不同的值都需要一個單獨的對象
3.3.4 使類成為不可變的方法 (絕不允許自身被子類化)
3.3.4.1 1 使類成為final
3.3.4.2 2 讓類的所有構(gòu)造器都變成私有的或者包級私有的沉衣,并添加公有的靜態(tài)工廠來替代公有的構(gòu)造器
3.3.4.3 靜態(tài)工廠方法除了允許多個實現(xiàn)類的靈活性之外郁副,這種方法還使得有可能通過改善靜態(tài)工廠的對象緩存能力,在后續(xù)的發(fā)行版中改進(jìn)該類的性能
3.3.4.4 還有許多其他優(yōu)勢豌习,比如存谎,提供一種其他功能的 構(gòu)造器 ,只需添加第二個靜態(tài)工廠肥隆,并且工廠的名字清楚地表明它的功能
3.3.5 如果你選擇讓自己的不可變類實現(xiàn)Serializable接口既荚,并且包含一個或多個指向可變對象的域,就必須提供一個顯式的readObject或者readResolve方法
3.3.6 除非有很好的理由要讓類成為一個可變的類栋艳,否則就應(yīng)該是不可變的
3.3.7 如果類不能被做成不可變的恰聘,仍然應(yīng)該盡可能地限制它的可變性。降低對象可存在的狀態(tài)數(shù)吸占,可以更容易地分析該對象的行為晴叨,同時降低出錯的可能性
3.4 16. 復(fù)合優(yōu)先于繼承
3.4.1 繼承是實現(xiàn)代碼重用的有力手段,但它并非永遠(yuǎn)是完成這項工作的最佳工具
3.4.2 與方法調(diào)用不同的是矾屯,繼承打破了封裝性
3.4.3 新類中的每個實例方法都可以調(diào)用被包含的現(xiàn)有類實例中對應(yīng)的方法兼蕊,并返回它的結(jié)果,這被稱為“轉(zhuǎn)發(fā)”件蚕,新類中的方法被稱為轉(zhuǎn)發(fā)方法
3.4.4 使用復(fù)合的類也被稱為包裝類孙技,這也正是“裝飾模式”
3.4.5 包裝類不適合用在回調(diào)框架中。 編寫轉(zhuǎn)發(fā)方法倒是有點瑣碎排作,但是只需要給每個接口編寫一次構(gòu)造器牵啦,轉(zhuǎn)發(fā)類則可以通過包含接口的包替你提供
3.4.6 只有當(dāng)子類真正是超類的子類型時,才適合用繼承
3.4.7 如果在適合于使用復(fù)合的地方使用繼承纽绍,則會不必要地暴露實現(xiàn)細(xì)節(jié)蕾久。這樣得到的API會把你限制在原始的實現(xiàn)上,永遠(yuǎn)限定了類的性能
3.5 17. 要么為繼承而設(shè)計拌夏,并提供文檔說明僧著,要么就禁止繼承
3.5.1 說明可覆蓋方法的自用性
3.5.2 好的文檔應(yīng)該描述一個給定的方法做了什么,而不是如何做到的
3.5.3 對于為了繼承而設(shè)計的類障簿,唯一的測試方法就是編寫子類
3.5.4 構(gòu)造器決不能調(diào)用可被覆蓋的方法
3.5.5 為了繼承而設(shè)計的類盹愚,對于這個類會有一些實質(zhì)性的限制
3.5.6 對于那些并非為了安全地進(jìn)行子類化而設(shè)計和編寫文檔的類,要禁止子類化
3.6 18. 接口優(yōu)于抽象類
3.6.1 現(xiàn)有的類可以很容易被更新站故,以實現(xiàn)新的接口
3.6.2 接口是定義mixin(混合類型)的理想選擇
3.6.3 接口允許我們構(gòu)造非層次結(jié)構(gòu)的類型框架
3.6.4 接口使得安全地增強(qiáng)類的功能成為可能
3.6.5 通過對你導(dǎo)出的每個重要接口都提供一個抽象的骨架實現(xiàn)類皆怕,把接口和抽象類的優(yōu)點結(jié)合起來
3.6.6 抽象類與接口相比有一個明顯優(yōu)勢:抽象類的演變比接口的演變要容易得多。如果在后續(xù)發(fā)行版中西篓,你希望在抽象類中增加新的方法愈腾,始終可以增加具體方法,它包含合理的默認(rèn)實現(xiàn)岂津。然后虱黄,該抽象類的所有實現(xiàn)都將提供這個新方法。對于接口,這樣做是行不通的
3.6.7 設(shè)計公有接口要非常謹(jǐn)慎。接口一旦被公開發(fā)行胶台,并且已被廣泛實現(xiàn)璧瞬,再想改變這個接口幾乎是不可能的
3.7 19. 接口只用于定義類型
3.7.1 有一種接口被稱為 常量接口。這種接口不包含任何方法决记,它只包含靜態(tài)final域,每個域都導(dǎo)出一個常量。使用這些常量的類實現(xiàn)這個接口危纫,以避免用類名來修飾常量名。
3.7.2 應(yīng)該將這種量導(dǎo)出
3.8 20. 類層次優(yōu)于標(biāo)簽類
3.8.1 缺點
3.8.1.1 充斥著樣板代碼乌庶,包括枚舉聲明叶摄、標(biāo)簽域以及條件語句
3.8.1.2 標(biāo)簽類過于冗長、容易出錯安拟,并且效率低下
3.9 21. 用函數(shù)對象表示策略
3.9.1 比較器函數(shù)代表一種為元素排序的策略
3.9.2 我們在設(shè)計具體的策略類時蛤吓,還需要定義一個策略接口
3.10 22. 優(yōu)先考慮靜態(tài)成員類
3.10.1 嵌套類是指被定義在另一個類的內(nèi)部的類。嵌套類有四種
3.10.1.1 靜態(tài)成員類
3.10.1.2 非靜態(tài)成員類
3.10.1.3 匿名類
3.10.1.4 局部類
3.10.2 如果聲明成員類不要求訪問外圍實例糠赦,就要始終把static修飾符放在它的聲明中
4 第5章 泛型
4.1 23. 請不要在新代碼中使用原生態(tài)類型
4.2 24. 消除非受檢警告
4.2.1 要盡可能消除每一個非受檢警告
4.2.2 如果無法消除警告会傲,同時可以證明引起警告的代碼是類型安全的,(只有在這種情況下才)可以用一個@SuppressWarning("uncheck")注解來禁止這條警告
4.3 25. 列表優(yōu)先于數(shù)組
4.3.1 數(shù)組與泛型相比拙泽,有兩個重要不同點

    4.3.1.1 1 數(shù)組是協(xié)變的
    4.3.1.2 2 數(shù)組是具體化的

4.4 26. 優(yōu)先考慮泛型
4.4.1 編寫自己的泛型會比較困難淌山,但是值得花些時間去學(xué)習(xí)如何編寫
4.5 27. 優(yōu)先考慮泛型方法
4.5.1 泛型方法就像泛型一樣,使用起來比要求客戶端轉(zhuǎn)換輸入?yún)?shù)并返回值的方法來得更加安全顾瞻,也更加容易泼疑。
4.5.2 就像泛型一樣,你應(yīng)該確保新方法可以不用轉(zhuǎn)換就能使用荷荤,這通常意味著要將它們泛型化
4.6 28. 利用有限制通配符來提升API的靈活性
4.6.1 <退渗? Extends E>
4.6.2 <? super E>
4.6.3 PECS 表示: producer-extends, consumer-super
4.6.4 所有的comparable和comparator都是消費者
4.7 29. 優(yōu)先考慮類型安全的異構(gòu)容器
5 第6章 枚舉和注解
5.1 第30條 用enum代替int常量
5.1.1 因為沒有可訪問的構(gòu)造器移稳,枚舉類型是真正的final
5.1.2 枚舉是實例受控的
5.1.3 它們是單例的泛型化,本質(zhì)上是單元素的枚舉
5.1.4 你可以增加或重新排列枚舉類型中的常量会油,而無需重新編譯它的客戶端代碼个粱,因為導(dǎo)出常量的域在枚舉類型和它的客戶端之間提供了一個隔離層:常量值并沒有被編譯到客戶端代碼中,而是在int枚舉模式之中
5.1.5 最終翻翩,可以通過調(diào)用toString方法將枚舉轉(zhuǎn)化成可打印的字符串
5.1.6 除了完善了int枚舉模式不足之外都许,枚舉類型還允許添加任意的方法和域,并實現(xiàn)任意接口
5.1.7 將不同的行為與每個枚舉常量關(guān)聯(lián)起來:在枚舉類型中聲明一個抽象的方法
5.1.7.1 pubic enum Operation{ PLUS{double apply(double x, double y){return x + y;}}, MINUS{double apply(double x, double y){return x - y;}}, TIMES{double apply(double x, double y){return x * y;}}, DIVIDE{double apply(double x, double y){return x / y;}}; abstract double apply(double x, double y); }
5.1.7.2 如果給第二版添加新常量嫂冻,你就不可能會忘記提供apply方法
5.1.8 特定于常量的方法實現(xiàn)可以與特定于常量的數(shù)據(jù)結(jié)合起來
5.1.8.1 pubic enum Operation{ PLUS("+") {double apply(double x, double y){return x + y;}}, MINUS("-") {double apply(double x, double y){return x - y;}}, TIMES("*") {double apply(double x, double y){return x * y;}}, DIVIDE("/") {double apply(double x, double y){return x / y;}}; private final String symbol; Operation(String symbol) {this.symbol = symbol;} @Override public String toString(){ return this.sybol;} abstract double apply(double x, double y); }
5.1.9 枚舉類型有一個自動產(chǎn)生的valueOf(String )方法胶征,它將常量的名字轉(zhuǎn)變成常量本身
5.1.10 策略枚舉
5.1.10.1 嵌套策略枚舉之后,枚舉中就不需要switch語句或者特定于常量的方法實現(xiàn)了桨仿。雖然這種模式?jīng)]有switch語句那么簡潔睛低,但更加安全,也更加靈活
5.2 第31條 用實例域代替序數(shù)
5.2.1 永遠(yuǎn)不要根據(jù)枚舉的序數(shù)導(dǎo)出與它關(guān)聯(lián)的值蹬敲,而是要將它保存在一個實例域中
5.2.2 ordinal()——大多數(shù)程序員都不需要這個方法暇昂,它是設(shè)計成用于像EnumSet和EnumMap這種基于枚舉的通用數(shù)據(jù)結(jié)構(gòu)的
5.3 第32條 用EnumSet代替位域
5.3.1 枚舉類型要用于集合中,沒有理由用位域來表示它們
5.4 第33條 用EnumMap代替序數(shù)索引
5.4.1 使用EnumMap伴嗡,運行速度可以與使用序數(shù)的程序相媲美急波,沒有不安全的轉(zhuǎn)換,不必手工標(biāo)注這些索引的輸出瘪校;計算數(shù)組索引時也不可能出錯
5.4.2 之所以能與通過序數(shù)索引的數(shù)組相媲美澄暮,是因為EnumMap在內(nèi)部使用了這種數(shù)組
5.4.3 最好不要用序數(shù)來索引數(shù)組,而要使用EnumMap
5.5 第34條 用接口模擬可伸縮的枚舉
5.5.1 雖然無法編寫可擴(kuò)展的枚舉類型阱扬,卻可以通過編寫接口以及實現(xiàn)該接口的基礎(chǔ)枚舉類型泣懊,對它進(jìn)行模擬
5.6 第35條 注解優(yōu)先于命名模式
5.6.1 示例
5.6.1.1 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test{ }
5.6.1.2 這種注解稱為元注解
5.7 第36條 堅持使用Override注解
5.7.1 能夠避免疏漏的 重載
5.8 第37條 用標(biāo)記接口定義類型
5.8.1 定義:沒有包含方法聲明的接口,而只是指明一個類實現(xiàn)了具有某種屬性的接口
6 第7章 方法
6.1 第38條 檢查參數(shù)的有效性
6.2 第39條 必要時進(jìn)行保護(hù)性拷貝
6.2.1 假設(shè)類的客戶端會盡其所能來破壞這個類的約束條件麻惶,因此你必須保護(hù)性地設(shè)計程序
6.2.2 為了保護(hù)類的內(nèi)部信息免受直接訪問修改的攻擊馍刮,對于構(gòu)造器的每個可變參數(shù)進(jìn)行保護(hù)性拷貝是必要的
6.2.3 對與參數(shù)類型可以被不可信任方子類化的參數(shù),請不要使用clone方法進(jìn)行保護(hù)性拷貝
6.2.4 雖然替換構(gòu)造器就可以成功地避免上述攻擊窃蹋,但是改變Period實例仍然是有可能的卡啰,因為它的訪問方法提供了對其可變內(nèi)部成員的訪問能力 為了防御這種攻擊,只需要修改訪問方法警没,使它返回可變內(nèi)部域的保護(hù)性拷貝即可
6.3 第40條 謹(jǐn)慎設(shè)計方法簽名
6.3.1 謹(jǐn)慎選擇方法的名稱
6.3.2 不要過于追求提供便利的方法
6.3.2.1 每個方法都應(yīng)該盡其所能匈辱。
6.3.2.2 方法太多會使類難以學(xué)習(xí)、使用杀迹、文檔化亡脸、測試和維護(hù)
6.3.2.3 只有當(dāng)一項操作被經(jīng)常使用時,才考慮為它提供快捷方法,如果不能確定浅碾,還是不提供為好
6.3.3 避免過長的參數(shù)列表
6.3.3.1 相同類型的長參數(shù)列表格外有害
6.3.3.2 例如大州,List接口提供了subList方法,返回子列表的視圖(view)
6.3.3.3 解決方法
6.3.3.3.1 1 分解為多個方法
6.3.3.3.2 2 創(chuàng)建輔助類
6.3.3.3.3 3 采用builder模式
6.3.3.4 對參數(shù)類型及穗,要優(yōu)先使用接口而不是類
6.3.3.5 對于boolean參數(shù)摧茴,要優(yōu)先使用兩個元素的枚舉類型
6.4 第41條 慎用重載
6.4.1 對于重載方法的選擇是靜態(tài)的绵载,而對于被覆蓋的方法的選擇則是動態(tài)的
6.4.2 安全而保守的策略是埂陆,永遠(yuǎn)不要導(dǎo)出兩個具有相同參數(shù)數(shù)目的重載方法
6.5 第42條 慎用可變參數(shù)
6.5.1 EnumSet類對它的靜態(tài)工廠使用這種方法,最大限度地減少創(chuàng)建枚舉集合的成本娃豹。枚舉集合為位域提供在性能方面有競爭力的替代方法
6.6 第43條 返回零長度的數(shù)組或者集合焚虱,而不是null
6.6.1 對于不返回任何元素的調(diào)用,每次都返回同一個零長度數(shù)組是有可能的懂版,因為零長度數(shù)組是不可變的
6.7 第44條 為所有導(dǎo)出的API元素編寫文檔注釋
6.7.1 為了正確地編寫API文檔鹃栽,必須在每個被導(dǎo)出的 類、接口躯畴、構(gòu)造器民鼓、方法和域聲明之前增加一個文檔注釋
6.7.2 方法的文檔注釋應(yīng)該簡潔地描述出它和客戶端之間的約定
6.7.2.1 precondition
6.7.2.2 postcondition
6.7.2.3 side effect
6.7.2.4 thread safety
6.7.3 可以使用HTML標(biāo)簽
6.7.4 使用{@code}標(biāo)簽
6.7.5 {@literal}
7 第8章 通用程序設(shè)計
7.1 第45條 將局部變量的作用域最小化
7.1.1 幾乎每個局部變量的聲明都應(yīng)該包含一個初始化表達(dá)式
7.1.2 使用for循環(huán),可以大大降低 “剪切-粘貼”錯誤
7.1.3 使用for循環(huán)與使用while相比還有另外一個優(yōu)勢:更簡短蓬抄,從而增強(qiáng)可讀性
7.2 第46條 for-each循環(huán)優(yōu)先于傳統(tǒng)的for循環(huán)
7.2.1 for-each循環(huán)不僅讓你遍歷集合和數(shù)組丰嘉,還讓你遍歷任何實現(xiàn)Iterable接口的對象
7.2.2 如果你在編寫的類型表示的是一組元素,即使你選擇不讓它實現(xiàn)Collection嚷缭,也要讓它實現(xiàn)Iterable饮亏。這樣可以允許用戶利用for-each循環(huán)遍歷你的類型
7.2.3 有三種常見情況無法使用for-each循環(huán)
7.2.3.1 過濾
7.2.3.2 轉(zhuǎn)換
7.2.3.3 平行迭代
7.3 第47條 了解和使用類庫
7.4 第48條 如果需要精確答案,請避免使用float和double
7.4.1 二進(jìn)制浮點運算
7.4.2 float和double不適合貨幣計算
7.4.3 使用BigDecimal阅爽、int或者long進(jìn)行
7.5 第49條 基本類型優(yōu)先于裝箱基本類型
7.5.1 裝箱類型的合理用處
7.5.1.1 作為集合中的元素路幸、鍵和值
7.5.1.2 在參數(shù)化類型中,必須使用裝箱基本類型作為類型參數(shù)
7.5.1.3 在反射調(diào)用時付翁,必須使用裝箱基本類型
7.6 第50條 如果其他類型更合適简肴,則盡量避免使用字符串
7.6.1 字符串不適合代替其他的值類型
7.6.2 字符串不適合代替枚舉類型
7.6.3 字符串不適合代替聚集類型
7.6.4 字符串不適合代替能力表
7.7 第51條 當(dāng)心字符串連接的性能
7.7.1 使用StringBuilder替代
7.8 第52條 通過接口引用對象
7.8.1 如果你養(yǎng)成了用接口作為類型的習(xí)慣,你的程序?qū)⒏屿`活
7.8.2 如果沒有合適的接口存在百侧,完全可以用類而不是接口來引用對象
7.9 第53條 接口優(yōu)先于反射機(jī)制
7.9.1 反射
7.9.1.1 喪失了編譯時類型檢查的好處
7.9.1.2 執(zhí)行反射訪問所需要的代碼非常笨拙和冗長
7.9.1.3 性能損失
7.10 第54條 謹(jǐn)慎地使用本地方法
7.10.1 使用本地方法提升性能的做法不值得提倡
7.11 第55條 謹(jǐn)慎地進(jìn)行優(yōu)化
7.11.1 優(yōu)化的弊大于利
7.11.2 要努力編寫好的程序而不是快的程序
7.11.3 努力避免那些限制性能的設(shè)計決策
7.11.4 要考慮API設(shè)計決策的性能后果
7.11.5 為了獲得好的性能而對API進(jìn)行包裝砰识,這是一種非常不好的想法
7.12 第56條 遵守普遍接受的命名規(guī)則
8 第9章 異常
8.1 第57條 只針對異常的情況才使用異常
8.1.1 基于異常的模式比標(biāo)準(zhǔn)模式要慢得多
8.2 第58條 對可恢復(fù)的情況使用受檢異常,對編程錯誤使用運行時異常
8.2.1 受檢異常
8.2.2 用運行時異常來表明編程錯誤
8.3 第59條 避免不必要地使用受檢異常
8.4 第60條 優(yōu)先使用標(biāo)準(zhǔn)異常
8.5 第61條 拋出與抽象相對應(yīng)的異常
8.5.1 更高層的實現(xiàn)應(yīng)該捕獲低層的異常移层,同時拋出可以按照高層抽象進(jìn)行解釋的異常
8.5.2 異常鏈
8.6 第62條 每個方法拋出的異常都要有文檔
8.6.1 單獨聲明受檢異常仍翰,使用Javadoc的@throws標(biāo)記
8.6.2 不要在非受檢異常上使用@throws
8.7 第63條 在細(xì)節(jié)消息中包含能捕獲失敗的信息
8.7.1 為了捕獲失敗,異常的細(xì)節(jié)信息應(yīng)該包含所有“對該異常有貢獻(xiàn)”的參數(shù)和域的值
8.8 第64條 努力使失敗保持原子性
8.8.1 失敗的方法調(diào)用應(yīng)該使對象保持在被調(diào)用之前的狀態(tài)
8.9 第65條 不要忽略異常
8.9.1 空的catch塊達(dá)不到應(yīng)有的目的
8.9.2 至少包含一條忽略的說明
9 第10章 并發(fā)
9.1 第66條 同步訪問共享的可變數(shù)據(jù)
9.1.1 Java語言規(guī)范保證讀或者寫一個變量是原子性的
9.1.2 volatile修飾符不執(zhí)行互斥訪問观话,但它可以保證任一線程在讀取該域時都將看到最近剛被寫入的值
9.1.3 使用volatile時予借,務(wù)必要小心,++操作并不是原子性的
9.1.4 AtomicInt、AtomicLong
9.1.4.1 getAndIncrement
9.1.5 多線程共享可變數(shù)據(jù)時灵迫,每個讀或者寫數(shù)據(jù)的線程都必行執(zhí)行同步
9.2 第67條 避免過度同步
9.3 第68條 executor和task優(yōu)先于線程
9.3.1 Executor FrameWork中有一個可以替代Timer的東西秦叛,即ScheduleThreadPoolExecutor 雖然就Timer更加容易,但executor更靈活瀑粥。Timer對于長期運行任務(wù)時會影響到定時準(zhǔn)確性挣跋。 如果Timer唯一的線程拋出未被捕獲異常,Timer就會停止執(zhí)行狞换,而executor支持多個線程避咆,并且優(yōu)雅地從拋出的未受檢異常的任務(wù)中恢復(fù)
9.4 第69條 并發(fā)工具優(yōu)先于wait和notify
9.4.1 既然正確地使用wait和notify比較困難,就應(yīng)該用更高級的并發(fā)工具來代替
9.4.2 concurrent工具分三類:Executor Framework修噪、并發(fā)集合 以及 同步器
9.4.2.1 并發(fā)集合為標(biāo)準(zhǔn)的集合接口(如List查库、Queue和Map)
9.4.2.1.1 ConcurrentHashMap出了提供卓越的并發(fā)性之外,速度也非郴魄恚快
9.4.2.1.2 優(yōu)先使用ConcurrentHashMap而不是Hashtable或者Collections.synchronizedMap
9.4.2.2 有些集合接口已經(jīng)通過阻塞操作進(jìn)行了擴(kuò)展樊销,他們會一直等待可以成功執(zhí)行為止
9.4.2.2.1 如BlockingQueue
9.4.2.2.2 不出所料,大多數(shù)ExecutorService實現(xiàn)(包括ThreadPoolExecutor)都使用BlockingQueue
9.4.2.3 同步器 是一些使線程能夠等待另一個線程的對象脏款,允許它們協(xié)調(diào)動作
9.4.2.3.1 最常用的是CountDownLatch和Semaphore
9.4.2.3.2 對于間歇式定時围苫,應(yīng)該使用System.nanoTime,更加精準(zhǔn)
9.4.2.3.3 傳遞給Timer方法的executor必須允許創(chuàng)建至少與指定并發(fā)級別一樣多的線程撤师,否則這個測試就永遠(yuǎn)不會結(jié)束剂府,這就是線程饑餓死鎖
9.4.3 使用wait和notify就像用“并發(fā)匯編語言”進(jìn)行編程一樣
9.4.4 維護(hù)時:一般情況下你應(yīng)該優(yōu)先使用notifyAll,而不是notify
9.5 第70條 線程安全性的文檔化
9.6 第71條 慎用延遲初始化
9.6.1 除非絕對必要丈氓,否則就不要這么做
9.6.2 在大多數(shù)情況下周循,正常的初始化要優(yōu)先于延遲初始化
9.6.3 如果處于性能考慮需要對實例域使用延遲初始化,就使用雙重檢查模式
9.7 第72條 不要依賴于線程調(diào)度器
9.7.1 任何依賴于線程調(diào)度器來達(dá)到正確性或者性能要求的程序万俗,很有可能都是不可移植的
9.7.2 不要依賴Thread.yield或者線程優(yōu)先級湾笛。這些設(shè)施僅僅對調(diào)度器作些按時
9.7.3 線程優(yōu)先級可以用來提高一個已經(jīng)能夠正常工作的程序的服務(wù)質(zhì)量,但永遠(yuǎn)不應(yīng)該用來“修正”一個原本不能正常工作的程序
9.8 第73條 避免使用線程組
10 第11章 序列化
10.1 第74條 謹(jǐn)慎實現(xiàn)Serializable接口
10.1.1 代價
10.1.1.1 降低了改變這個類的實現(xiàn)的靈活性
10.1.1.2 增加了出現(xiàn)Bug和安全漏洞的可能性
10.1.1.3 相關(guān)的測試負(fù)擔(dān)增加
10.2 第75條 考慮使用自定義的序列化形式
10.3 第76條 保護(hù)性地編寫readObject方法
10.4 第77條 對于實例控制闰歪,枚舉類型優(yōu)先于readResolve
10.5 第78條 考慮用序列化代理代替序列化實例

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末嚎研,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子库倘,更是在濱河造成了極大的恐慌临扮,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件教翩,死亡現(xiàn)場離奇詭異杆勇,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)饱亿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門蚜退,熙熙樓的掌柜王于貴愁眉苦臉地迎上來闰靴,“玉大人,你說我怎么就攤上這事钻注÷烨遥” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵幅恋,是天一觀的道長杏死。 經(jīng)常有香客問我,道長捆交,這世上最難降的妖魔是什么淑翼? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮零渐,結(jié)果婚禮上窒舟,老公的妹妹穿的比我還像新娘系忙。我一直安慰自己诵盼,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布银还。 她就那樣靜靜地躺著风宁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪蛹疯。 梳的紋絲不亂的頭發(fā)上戒财,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天,我揣著相機(jī)與錄音捺弦,去河邊找鬼饮寞。 笑死,一個胖子當(dāng)著我的面吹牛列吼,可吹牛的內(nèi)容都是我干的幽崩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼寞钥,長吁一口氣:“原來是場噩夢啊……” “哼慌申!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起理郑,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤蹄溉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后您炉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體柒爵,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年赚爵,在試婚紗的時候發(fā)現(xiàn)自己被綠了棉胀。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宴霸。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖膏蚓,靈堂內(nèi)的尸體忽然破棺而出瓢谢,到底是詐尸還是另有隱情,我是刑警寧澤驮瞧,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布氓扛,位于F島的核電站,受9級特大地震影響论笔,放射性物質(zhì)發(fā)生泄漏采郎。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一狂魔、第九天 我趴在偏房一處隱蔽的房頂上張望蒜埋。 院中可真熱鬧,春花似錦最楷、人聲如沸整份。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烈评。三九已至,卻和暖如春犯建,著一層夾襖步出監(jiān)牢的瞬間讲冠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工适瓦, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留竿开,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓玻熙,卻偏偏與公主長得像否彩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子揭芍,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 【1】7胳搞,9,-1称杨,5肌毅,( ) A、4姑原;B悬而、2;C锭汛、-1笨奠;D袭蝗、-3 分析:選D,7+9=16般婆;9+(-1)=8到腥;(...
    Alex_bingo閱讀 18,925評論 1 19
  • 對象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法,而不是構(gòu)造函數(shù)創(chuàng)建對象:僅僅是創(chuàng)建對象的方法蔚袍,并非Fa...
    孫小磊閱讀 1,982評論 0 3
  • 第2章 創(chuàng)建和銷毀對象 第1條:考慮用靜態(tài)工廠方法代替構(gòu)造方法 靜態(tài)工廠方法與構(gòu)造方法的不同 優(yōu)點: 靜態(tài)工廠方法...
    QM閱讀 612評論 0 51
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報批稿:20170802 前言: 排版 ...
    庭說閱讀 10,983評論 6 13
  • 平遙古城的那一天一夜乡范,我是最孤獨的,熱鬧的大街啤咽,我是孤獨的晋辆,大街上的歡聲笑語,我是孤獨的宇整,美麗的風(fēng)景瓶佳,我是...
    王神馬閱讀 147評論 0 0