第3版前言
1997年,Java才面世不久,James Gosling(Java之父)稱之為“超級(jí)簡單的藍(lán)領(lǐng)語言”[Gosling97]。幾乎與此同時(shí),Bjarne Stroustrup(C++之父)則將C++稱為“多范式語言”(multi-paradigm language),因?yàn)椤八c那些只支持單一編程方法的程序語言有著天壤之別”[Stroustrup95]。Stroustrup曾發(fā)出過這樣的警告:
正如大多數(shù)剛面世的語言一樣,Java的相對(duì)簡單性,很可能一部分是出于錯(cuò)覺,一部分是因?yàn)槠渖胁煌暾鴮?dǎo)致的結(jié)果。隨著時(shí)間的推移,Java在規(guī)模和復(fù)雜度方面都會(huì)顯著增長。到那時(shí),其規(guī)?赡艹孰p倍甚至三倍增長,并產(chǎn)生大量依賴于實(shí)現(xiàn)的擴(kuò)展或者類庫[Stroustrup]。
現(xiàn)在,二十年過去了,坦白地說,Gosling和Stroustrup說的都沒有錯(cuò)。Java現(xiàn)在果然是既龐大又復(fù)雜,許多東西都帶有多個(gè)抽象,從并發(fā)執(zhí)行,到迭代,再到日期和時(shí)間的表示法。
隨著Java平臺(tái)的發(fā)展,我的熱情有所降溫,但我依然鐘愛Java?紤]到Java日益增加的規(guī)模和復(fù)雜度,對(duì)于最前沿的最佳實(shí)踐指導(dǎo)的需求成了重中之重。在本書中,我將不遺余力地為讀者提供這樣的指導(dǎo)。希望這一版能夠在堅(jiān)持前兩個(gè)版本的精神的前提下,繼續(xù)滿足讀者的最新需求。
簡單即美,但要做到大道至簡卻實(shí)屬不易。
Joshua Bloch
San Jose, California
2017年11月
附:近年來,我在業(yè)界的最佳實(shí)踐方面花費(fèi)了大量的精力。自20世紀(jì)50年代誕生這個(gè)行業(yè)以來,我們已經(jīng)自由地重新實(shí)現(xiàn)了彼此的API。這個(gè)實(shí)踐對(duì)于計(jì)算機(jī)技術(shù)的快速成功至關(guān)重要。我始終積極地致力于維護(hù)這種自由[CompSci17],并且鼓勵(lì)你們也加入到這個(gè)行列中來。我們的專業(yè)要想持續(xù)健康地發(fā)展,確保重新實(shí)現(xiàn)各自API的權(quán)利顯得尤為重要。
第2版前言
自從我于2001年寫了本書的第1版之后,Java平臺(tái)又發(fā)生了很多變化,是該出第2版的時(shí)候了。Java 5中最為重要的變化是增加了泛型、枚舉類型、注解、自動(dòng)裝箱和for-each
循環(huán)。其次是增加了新的并發(fā)類庫:java.util.concurrent。我和Gilad Bracha一起,有幸?guī)ьI(lǐng)團(tuán)隊(duì)設(shè)計(jì)了最新的語言特性。我還有幸參加了設(shè)計(jì)和開發(fā)并發(fā)類庫的團(tuán)隊(duì),這個(gè)團(tuán)隊(duì)由Doug Lea領(lǐng)導(dǎo)。
Java平臺(tái)中另一個(gè)大的變化在于廣泛采用了現(xiàn)代的IDE(Integrated Development Envi-ronment),例如Eclipse、IntelliJ IDEA和NetBeans,以及靜態(tài)分析工具的IDE,如FindBugs。雖然我還未參與這部分工作,但已經(jīng)從中受益匪淺,并且很清楚它們對(duì)Java開發(fā)體驗(yàn)所帶來的影響。
2004年,我離開Sun公司到了Google公司工作,但在過去的4年中,我仍然繼續(xù)參與Java平臺(tái)的開發(fā),在Google公司和JCP(Java Community Process)的大力幫助下,繼續(xù)并發(fā)和集合API的開發(fā)。我還有幸利用Java平臺(tái)去開發(fā)供Google內(nèi)部使用的類庫。現(xiàn)在我了解了作為一名用戶的感受。
我在2001年編寫第1版的時(shí)候,主要目的是與讀者分享我的經(jīng)驗(yàn),便于讓大家避免我所走過的彎路,使大家更容易成功。新版仍然大量采用來自Java平臺(tái)類庫的真實(shí)范例。
第1版所帶來的反應(yīng)遠(yuǎn)遠(yuǎn)超出了我最大的預(yù)期。我在收集所有新的資料以使本書保持最新時(shí),盡可能地保持了資料的真實(shí)。毫無疑問,本書的篇幅肯定會(huì)增加,從57個(gè)條目發(fā)展到了78個(gè)。我不僅增加了23個(gè)條目,并且修改了原來的所有資料,并刪去了一些已經(jīng)過時(shí)的條目。在附錄中,你可以看到本書中的內(nèi)容與第1版的內(nèi)容的對(duì)照情況。
在第1版的前言中我說過:Java程序設(shè)計(jì)語言和它的類庫非常有益于代碼質(zhì)量與效率的提高,并且使得用Java進(jìn)行編碼成為一種樂趣。Java 5和Java 6發(fā)行版中的變化是好事,這也使Java平臺(tái)日趨完善,F(xiàn)在這個(gè)平臺(tái)比2001年的要大得多,也復(fù)雜得多,但是一旦掌握了使用新特性的模式和習(xí)慣用法,它們就會(huì)使你的程序變得更完美,使你的工作變得更輕松。我希望第2版能夠體現(xiàn)出我對(duì)Java平臺(tái)持續(xù)的熱情,并將這種熱情傳遞給你,幫助你更加高效和愉快地使用Java平臺(tái)及其新的特性。
Joshua Bloch
San Jose, California
2008年4月
第1版前言
1996年,我打點(diǎn)行囊,西行來到了當(dāng)時(shí)的JavaSoft,因?yàn)槲液芮宄抢飳?huì)出現(xiàn)奇跡。在這5年間,我是Java平臺(tái)庫的架構(gòu)師。我設(shè)計(jì)、實(shí)現(xiàn)和維護(hù)過許多類庫,同時(shí)也擔(dān)任其他一些庫的技術(shù)顧問。隨著Java平臺(tái)的成熟和壯大,主持這些類庫的設(shè)計(jì)工作是一個(gè)人一生中難得的機(jī)會(huì)。毫不夸張地說,我有幸與一些當(dāng)代最杰出的軟件工程師一起工作。在這個(gè)過程中,我學(xué)到了許多關(guān)于Java程序設(shè)計(jì)語言的知識(shí)——它能夠做什么,不能夠做什么,以及如何最有效地使用這門語言及其類庫。
本書是我的一次嘗試,希望與你分享我的經(jīng)驗(yàn),你可以因此而吸取我的經(jīng)驗(yàn),避免重復(fù)我的失敗。本書中我借用了Scott Meyers的《Effective C++》一書的格式,該書中包含50個(gè)條目,每個(gè)條目給出一條用于改進(jìn)程序和設(shè)計(jì)的規(guī)則。我覺得這種格式非常有效,希望你也有這樣的感覺。
在許多例子中,我冒昧地使用了Java平臺(tái)庫中的真實(shí)例子來說明相應(yīng)的條目。在介紹那些做得不是很完美的工作時(shí),我盡量使用我自己編寫的代碼,但是偶爾我也會(huì)使用其他同事的代碼。盡管我盡力做得更好一點(diǎn),但是如果我真的冒犯了他人,我先在這里致以最誠摯的歉意。引用反面例子是出于協(xié)作的精神,而不是要羞辱例子中的做法,我希望大家都能夠從我們過去的錯(cuò)誤經(jīng)歷中得到啟發(fā)。
盡管本書并不只是針對(duì)可重用組件開發(fā)人員的,但是過去20多年來我編寫此類組件的經(jīng)歷一定會(huì)影響這本書。我很自然地會(huì)按照可導(dǎo)出API(Application Programming Interface)的方式來思考問題,而且我建議你也這樣做。即使你并沒有開發(fā)可重用的組件,這樣的思考方法也將有助于你提升軟件的質(zhì)量。進(jìn)一步來說,毫無意識(shí)地編寫可重用組件的情形并不少見:你編寫了一些很有用的代碼,然后在同伴之間共享,不久之后你就有了很多用戶。這時(shí)候,你就不能隨心所欲地改變API了,并且如果你剛開始編寫軟件的時(shí)候在設(shè)計(jì)API上付出了較多的努力,那么這時(shí)你就會(huì)非常慶幸了。
我把焦點(diǎn)放在API的設(shè)計(jì)上,這對(duì)于那些熱衷于新興的輕量級(jí)軟件開發(fā)方法學(xué)(比如Extreme Programming,即“極限編程”,簡稱XP)的讀者來說,也許會(huì)顯得有點(diǎn)不太自然。這些方法學(xué)強(qiáng)調(diào)編寫最簡單的、能夠工作的程序。如果你正在使用此類的某種程序設(shè)計(jì)方法,那么你會(huì)發(fā)現(xiàn),把焦點(diǎn)放在API設(shè)計(jì)上對(duì)于“重構(gòu)”(refactoring)過程是多么有益。重構(gòu)的基本目標(biāo)是改進(jìn)系統(tǒng)結(jié)構(gòu),以及避免代碼重復(fù)。如果系統(tǒng)的組件沒有設(shè)計(jì)良好的API,要達(dá)到這樣的目標(biāo)則是不可能的。
沒有一門語言是完美的,但是有些語言非常優(yōu)秀。我認(rèn)為Java程序設(shè)計(jì)語言及其類庫非常有益于提高代碼質(zhì)量和工作效率,并使得編碼工作成為一種樂趣。我希望本書能夠抓住我的熱情并傳遞給你,幫助你更有效地利用Java語言,使工作變得更加愉快。
Joshua Bloch
Cupertino, California
2001年4月
◆譯者序 ◆
Java從1997年誕生到日趨完善,經(jīng)過了20多年不斷的發(fā)展壯大,已經(jīng)擁有了近千萬開發(fā)人員。如何編寫出更清晰、更正確、更健壯且更易于重用的代碼,是大家所追求的目標(biāo)。本書是經(jīng)典Jolt獲獎(jiǎng)作品《Effective Java》的第3版,對(duì)上一版內(nèi)容進(jìn)行了徹底的更新,涵蓋了自2001年第1版之后所引入的Java SE 5和Java SE 6的新特性,以及2008年第2版之后所引入的Java SE 7和Java SE 8以及Java SE 9的新特性。作者探索了新的設(shè)計(jì)模式和語言習(xí)慣用法,介紹了如何充分利用從泛型到枚舉、從注解到自動(dòng)裝箱的各種特性,幫助讀者更加有效地使用Java編程語言及其基本類庫:java.lang、java.util和java.io,以及子包,如java.util.concurrent和java.util.function等。本書的作者Joshua Bloch曾經(jīng)是Sun公司的杰出工程師和Google公司的首席Java架構(gòu)師,帶領(lǐng)團(tuán)隊(duì)設(shè)計(jì)和實(shí)現(xiàn)過無數(shù)的Java平臺(tái)特性,包括JDK 5.0語言增強(qiáng)版和獲獎(jiǎng)的Java Collections Framework。在本書中,他為我們帶來了90條程序員必備的經(jīng)驗(yàn)法則:針對(duì)你每天都會(huì)遇到的編程問題提出了最有效、最實(shí)用的解決方案。
書中的每一章都包含幾個(gè)“條目”,以簡潔的形式呈現(xiàn),自成獨(dú)立的短文,它們提出了具體的建議、對(duì)于Java平臺(tái)精妙之處的獨(dú)到見解,并提供優(yōu)秀的代碼范例。每個(gè)條目的綜合描述和解釋都闡明了應(yīng)該怎么做、不應(yīng)該怎么做,以及為什么。通過閱讀貫穿全書的透徹的技術(shù)剖析與完整的示例代碼,認(rèn)真理解并加以實(shí)踐,必定會(huì)從中受益匪淺。書中介紹的示例代碼清晰易懂,也可以作為日常工作的參考指南。
讀者對(duì)象
本書不是針對(duì)初學(xué)者的,讀者至少需要熟悉Java程序設(shè)計(jì)語言。如果你連equals()、toString()、hashCode()都還不了解的話,建議先去看些優(yōu)秀的Java入門書籍,之后再來閱讀本書。如果你在Java開發(fā)方面已經(jīng)有一定的經(jīng)驗(yàn),想更加深入地了解Java編程語言,成為一名更優(yōu)秀、更高效的Java開發(fā)人員,那么,建議你用心研讀本書。
內(nèi)容形式
本書分為12章共90個(gè)條目,涵蓋了Java 5.0 / 6.0 / 7.0 / 8.0 / 9.0的種種技術(shù)要點(diǎn)。與第2版相比,本書刪除了“C語言結(jié)構(gòu)的替代”一章,增加了Java 7及之后所引入的新特性:Lambda表達(dá)式、Stream、Optional類、接口中的默認(rèn)方法、try-with-resources、
@SafeVarargs注解、Module模塊化 。數(shù)量上從78個(gè)條目發(fā)展到了90個(gè),不僅增加了12個(gè)條目,并對(duì)原來的所有資料都進(jìn)行了全面的修改,刪去了一些已經(jīng)過時(shí)的條目。但是,各章之間并沒有嚴(yán)格的前后順序關(guān)系,你可以隨意選擇感興趣的章節(jié)進(jìn)行閱讀。當(dāng)然,如果你想馬上知道第3版究竟有哪些變化,可以參閱附錄。
本書重點(diǎn)講述了Java 5所引入的全新的泛型、枚舉、注解、自動(dòng)裝箱、for-each循環(huán)、可變參數(shù)、并發(fā)機(jī)制,還包括對(duì)象、類、類庫、方法和序列化這些經(jīng)典主題的全新技術(shù)與最佳實(shí)踐,以及如何避免Java編程語言中常被誤解的細(xì)微之處:陷阱和缺陷,并重點(diǎn)關(guān)注了Java語言本身和最基本的類庫(java.lang、java.util)和一些擴(kuò)展(java.util.concurrent和java.io等)。
主要章節(jié)簡介
第1章為引言。
第2章闡述何時(shí)以及如何創(chuàng)建對(duì)象,何時(shí)以及如何避免創(chuàng)建對(duì)象,如何確保它們能夠適時(shí)地銷毀,以及如何管理對(duì)象銷毀之前必須進(jìn)行的各種清除動(dòng)作。
第3章闡述對(duì)于所有對(duì)象都通用的方法,你會(huì)從中獲知對(duì)equals、hashCode、toString、clone、finalize以及Comparable.compareTo方法相當(dāng)深入的分析,從而避免今后在這些問題上再次犯錯(cuò)。
第4章闡述作為Java程序設(shè)計(jì)語言的核心以及Java語言的基本抽象單元(類和接口)在使用上的一些指導(dǎo)原則,幫助你更好地利用這些元素,設(shè)計(jì)出更加有用、健壯和靈活的類與接口。
第5章和第6章中分別闡述在Java 1.5發(fā)行版本中新增加的泛型(Generic)以及枚舉(Enum)和注解(Annotation)的最佳實(shí)踐,教你如何最大限度地享有這些優(yōu)勢(shì),并使整個(gè)過程盡可能地簡單化。
第7章專門討論在Java 8中新增的函數(shù)接口(Functional Interface)、Lambda表達(dá)式和方法引用(Method Reference),使創(chuàng)建函數(shù)對(duì)象(Function Object)變得更加容易。接著探討為處理數(shù)據(jù)元素的序列提供了類庫級(jí)別支持的Stream API,以及如何最佳地利用這些機(jī)制。
第8章討論方法設(shè)計(jì)的幾個(gè)方面:如何處理參數(shù)和返回值,如何設(shè)計(jì)方法簽名,如何為方法編寫文檔,從而使方法設(shè)計(jì)在可用性、健壯性和靈活性上有進(jìn)一步的提升。
第9章主要討論Java語言的具體細(xì)節(jié),討論了局部變量的處理、控制結(jié)構(gòu)、類庫的使用、各種數(shù)據(jù)類型的用法,以及兩種不是由語言本身提供的機(jī)制(Reflection和Native Method,反射機(jī)制和本地方法)的用法,并討論了優(yōu)化和命名慣例。
第10章闡述如何充分發(fā)揮異常的優(yōu)點(diǎn)來提高程序的可讀性、可靠性和可維護(hù)性,以及減少異常使用不當(dāng)所帶來的負(fù)面影響,并提供了一些關(guān)于有效使用異常的指導(dǎo)原則。
第11章闡述如何幫助你編寫出清晰、正確、文檔組織良好的并發(fā)程序,比如如何避免過度同步,優(yōu)先采用Executor Framework、并發(fā)集合(Concurrent Collection)、同步器(Synch-ronizer),以及是否需要依賴于線程調(diào)度器等。
第12章闡述序列化方面的技術(shù),并且有一項(xiàng)值得特別提及的特性,就是序列化代理(Serialization Proxy)模式,它可以幫助你避免對(duì)象序列化的許多缺陷。
舉個(gè)例子,就序列化技術(shù)來講,HTTP會(huì)話狀態(tài)為什么可以緩存?RMI的異常為什么可以從服務(wù)器端傳遞到客戶端?GUI組件為什么可以被發(fā)送、保存和恢復(fù)呢?是因?yàn)樗鼈儗?shí)現(xiàn)了Serializable接口嗎?如果超類沒有提供可訪問的無參構(gòu)造器,它的子類可以被序列化嗎?當(dāng)一個(gè)實(shí)例采用默認(rèn)的序列化形式,并且給某些域標(biāo)記為transient,那么當(dāng)實(shí)例反序列化回來后,這些標(biāo)記為transient域的值各是些什么呢?這些問題如果你現(xiàn)在不能馬上回答,或者不能確定,也沒有關(guān)系,請(qǐng)仔細(xì)閱讀本書,你將會(huì)對(duì)它們有更深入與透徹的理解。
技術(shù)范圍
雖然本書所討論的是更深層次的Java開發(fā)技術(shù),講述的內(nèi)容深入,涉及面又相當(dāng)廣泛,但是它并沒有涉及圖形用戶界面編程、企業(yè)級(jí)API以及移動(dòng)設(shè)備方面的技術(shù),不過在一些條目中會(huì)不時(shí)地討論到其他相關(guān)的類庫。
這是一本分享經(jīng)驗(yàn)與指引你少走彎路的經(jīng)典著作,針對(duì)如何編寫高效、設(shè)計(jì)優(yōu)良的程序提出了最實(shí)用、最權(quán)威的指導(dǎo)方針,是Java開發(fā)人員案頭上的一本不可或缺的參考書。
本書由我組織進(jìn)行翻譯,并負(fù)責(zé)本書所有章節(jié)的全面審校。參與翻譯和審校的還有:楊春花、榮浩、邱慶舉、萬國輝、陸志平、姜法有、王琳、林儀明、凌家亮、李勇、劉傳飛、王建旭、程旭文、羅興、翟育明、楊征和陳建都。
雖然我們?cè)诜g過程中竭力追求信、達(dá)、雅,但限于自身水平,也許仍有不足,還望各位讀者不吝指正。關(guān)于本書的翻譯和翻譯時(shí)采用的術(shù)語以及相關(guān)的技術(shù)討論大家可以訪問我的博客http://YuLimin.ItEye.com,也可以發(fā)郵件到Y(jié)uLimin @ 163.com與我交流。
在這里,我要感謝在翻譯過程中一起討論并幫助我的朋友們,他們是:滿江紅開放技術(shù)研究組織創(chuàng)始人曹曉鋼,Spring中文站創(chuàng)始人楊戈(Yanger),SpringSide創(chuàng)始人肖樺(江南白衣)和來自寶島臺(tái)灣的李日貴(jini)、林康司(koji)、林信良(caterpillar),在此再次深表感謝。
最后,感謝華章公司的兩位編輯陳佳媛與關(guān)敏,她們耐心、細(xì)致地審校了全書,使本書得到了極大的改善。贊!
快樂分享,實(shí)踐出真知,最后,祝大家能夠像我一樣在閱讀中享受本書帶來的樂趣!
Read a bit and take it out, then come back read some more.
俞黎敏
2018年10月24日于港珠澳大橋開通之時(shí)
◆推薦序 ◆
如果有一個(gè)同事這樣對(duì)你說:“我的配偶今天晚上在家里制造了一頓不同尋常的晚餐,你愿意來參加嗎?”(Spouse of me this night today manufactures the unusual meal in a home. You will join?)這時(shí)候你腦子里可能會(huì)想到三件事情:第一,滿腦子的疑惑;第二,英語肯定不是這位同事的母語;第三,同事是在邀請(qǐng)你參加他的家庭晚宴。
如果你曾經(jīng)學(xué)習(xí)過第二種語言,并且嘗試過在課堂之外使用這種語言,就該知道有三件事情是必須掌握的:這門語言的結(jié)構(gòu)是怎么樣的(語法),如何命名你想談?wù)摰氖挛铮ㄔ~匯),以及如何以慣用和高效的方式來表達(dá)日常事物(用法)。在課堂上大多只涉及前面兩點(diǎn),當(dāng)你使出渾身解數(shù)想讓對(duì)方明白你的意思時(shí),卻常常發(fā)現(xiàn)母語人士或當(dāng)?shù)厝藢?duì)你的表述忍俊不禁。
程序設(shè)計(jì)語言也是如此。你需要理解語言的核心:它是面向算法的,還是面向函數(shù)的或者是面向?qū)ο蟮?你需要知道詞匯表:標(biāo)準(zhǔn)類庫提供了哪些數(shù)據(jù)結(jié)構(gòu)、操作和功能?你還需要熟悉如何用習(xí)慣和高效的方式來構(gòu)建代碼。關(guān)于程序設(shè)計(jì)語言的書籍通常只涉及前兩點(diǎn),或者只是蜻蜓點(diǎn)水般地介紹一下用法。也許是因?yàn)榍皟牲c(diǎn)比較容易編寫。語法和詞匯是語言本身固有的特性,用法則反映了使用這門語言的群體特征。
例如,Java程序設(shè)計(jì)語言是一門支持單繼承的面向?qū)ο蟪绦蛟O(shè)計(jì)語言,在每個(gè)方法的內(nèi)部,它也支持命令式的(面向語句的)編碼風(fēng)格。Java類庫提供了對(duì)圖形顯示、網(wǎng)絡(luò)、分布式計(jì)算和安全性的支持。但是,如何把這門語言以最佳的方式運(yùn)用到實(shí)踐中呢?
還有一點(diǎn):程序與口語中的句子以及大多數(shù)書籍和雜志都不同,它會(huì)隨著時(shí)間的推移而發(fā)生變化。僅僅編寫出能夠有效地工作并且能夠被別人理解的代碼往往是不夠的,我們還必須把代碼組織成易于修改的形式。針對(duì)某個(gè)任務(wù)T可能會(huì)有10種不同的編碼方法,而在這10種方法中,可能有7種方法是笨拙、低效或者難以理解的。而在剩下的3種編碼方法中,哪一種會(huì)是最接近任務(wù)T的下一年度發(fā)行版本的代碼呢?
目前有大量的書籍可以供你學(xué)習(xí)Java程序設(shè)計(jì)語言的語法,包括《The Java Programming
Language》(作者是Arnold、Gosling和Holmes),以及《The Java Language Specification》(作者是Gosling、Joy和Bracha)。同樣,介紹Java程序設(shè)計(jì)語言相關(guān)的類庫和API的書籍也不少。
本書將解決你的第三種需求:習(xí)慣和高效的用法。作者Joshua Bloch在Sun公司多年來一直從事Java編程語言的擴(kuò)展、實(shí)現(xiàn)和使用的工作;他還大量地閱讀了其他人的代碼,包括我的代碼。他在本書中提出了許多很好的建議,系統(tǒng)地把這些建議組織起來,旨在告訴讀者如何更好地構(gòu)建代碼,以便它們能夠更好地工作,也便于其他人能夠理解這些代碼,將來對(duì)代碼進(jìn)行修改和改善的時(shí)候不至于那么頭疼。甚至,你的程序也會(huì)因此而變得更加令人愉悅、更加優(yōu)美和雅致。
Guy L. Steele Jr.
馬薩諸塞州,伯靈頓
2001年4月
推薦序
譯者序
前言
致謝
第1章 引言 1
第2章 創(chuàng)建和銷毀對(duì)象 4
第1條:用靜態(tài)工廠方法代替構(gòu)造器 4
第2條:遇到多個(gè)構(gòu)造器參數(shù)時(shí)要考慮使用構(gòu)建器 8
第3條:用私有構(gòu)造器或者枚舉類型強(qiáng)化Singleton屬性 13
第4條:通過私有構(gòu)造器強(qiáng)化不可實(shí)例化的能力 15
第5條:優(yōu)先考慮依賴注入來引用資源 16
第6條:避免創(chuàng)建不必要的對(duì)象 18
第7條:消除過期的對(duì)象引用 20
第8條:避免使用終結(jié)方法和清除方法 23
第9條:try-with-resources優(yōu)先于try-f?inally 27
第3章 對(duì)于所有對(duì)象都通用的方法 30
第10條:覆蓋equals時(shí)請(qǐng)遵守通用約定 30
第11條:覆蓋equals時(shí)總要覆蓋hashCode 40
第12條:始終要覆蓋toString 44
第13條:謹(jǐn)慎地覆蓋clone 46
第14條:考慮實(shí)現(xiàn)Comparable接口 53
第4章 類和接口 59
第15條:使類和成員的可訪問性最小化 59
第16條:要在公有類而非公有域中使用訪問方法 62
第17條:使可變性最小化 64
第18條:復(fù)合優(yōu)先于繼承 70
第19條:要么設(shè)計(jì)繼承并提供文檔說明,要么禁止繼承 75
第20條:接口優(yōu)于抽象類 79
第21條:為后代設(shè)計(jì)接口 83
第22條:接口只用于定義類型 85
第23條:類層次優(yōu)于標(biāo)簽類 86
第24條:靜態(tài)成員類優(yōu)于非靜態(tài)成員類 88
第25條:限制源文件為單個(gè)頂級(jí)類 91
第5章 泛型 93
第26條:請(qǐng)不要使用原生態(tài)類型 93
第27條:消除非受檢的警告 97
第28條:列表優(yōu)于數(shù)組 99
第29條:優(yōu)先考慮泛型 102
第30條:優(yōu)先考慮泛型方法 106
第31條:利用有限制通配符來提升API的靈活性 109
第32條:謹(jǐn)慎并用泛型和可變參數(shù) 114
第33條:優(yōu)先考慮類型安全的異構(gòu)容器 118
第6章 枚舉和注解 123
第34條:用enum代替int常量 123
第35條:用實(shí)例域代替序數(shù) 131
第36條:用EnumSet代替位域 132
第37條:用EnumMap代替序數(shù)索引 134
第38條:用接口模擬可擴(kuò)展的枚舉 138
第39條:注解優(yōu)先于命名模式 140
第40條:堅(jiān)持使用Override注解 147
第41條:用標(biāo)記接口定義類型 149
第7章 Lambda和Stream 151
第42條:Lambda優(yōu)先于匿名類 151
第43條:方法引用優(yōu)先于Lambda 154
第44條:堅(jiān)持使用標(biāo)準(zhǔn)的函數(shù)接口 156
第45條:謹(jǐn)慎使用Stream 159
第46條:優(yōu)先選擇Stream中無副作用的函數(shù) 164
第47條:Stream要優(yōu)先用Collection作為返回類型 168
第48條:謹(jǐn)慎使用Stream并行 172
第8章 方法 176
第49條:檢查參數(shù)的有效性 176
第50條:必要時(shí)進(jìn)行保護(hù)性拷貝 179
第51條:謹(jǐn)慎設(shè)計(jì)方法簽名 182
第52條:慎用重載 184
第53條:慎用可變參數(shù) 189
第54條:返回零長度的數(shù)組或者集合,而不是null 190
第55條:謹(jǐn)慎返回optinal 192
第56條:為所有導(dǎo)出的API元素編寫文檔注釋 196
第9章 通用編程 202
第57條:將局部變量的作用域最小化 202
第58條:for-each循環(huán)優(yōu)先于傳統(tǒng)的for循環(huán) 204
第59條:了解和使用類庫 207
第60條:如果需要精確的答案,請(qǐng)避免使用f?loat和double 209
第61條:基本類型優(yōu)先于裝箱基本類型 211
第62條:如果其他類型更適合,則盡量避免使用字符串 213
第63條:了解字符串連接的性能 215
第64條:通過接口引用對(duì)象 216
第65條:接口優(yōu)先于反射機(jī)制 218
第66條:謹(jǐn)慎地使用本地方法 220
第67條:謹(jǐn)慎地進(jìn)行優(yōu)化 221
第68條:遵守普遍接受的命名慣例 223
第10章 異常 227
第69條:只針對(duì)異常的情況才使用異常 227
第70條:對(duì)可恢復(fù)的情況使用受檢異常,對(duì)編程錯(cuò)誤使用運(yùn)行時(shí)異常 229
第71條:避免不必要地使用受檢異常 231
第72條:優(yōu)先使用標(biāo)準(zhǔn)的異常 232
第73條:拋出與抽象對(duì)應(yīng)的異常 234
第74條:每個(gè)方法拋出的所有異常都要建立文檔 235
第75條:在細(xì)節(jié)消息中包含失敗-捕獲信息 237
第76條:努力使失敗保持原子性 238
第77條:不要忽略異常 239
第11章 并發(fā) 241
第78條:同步訪問共享的可變數(shù)據(jù) 241
第79條:避免過度同步 245
第80條:executor、task和stream優(yōu)先于線程 250
第81條:并發(fā)工具優(yōu)先于wait和notify 251
第82條:線程安全性的文檔化 256
第83條:慎用延遲初始化 258
第84條:不要依賴于線程調(diào)度器 261
第12章 序列化 263
第85條:其他方法優(yōu)先于Java序列化 263
第86條:謹(jǐn)慎地實(shí)現(xiàn)Serializable接口 266
第87條:考慮使用自定義的序列化形式 269
第88條:保護(hù)性地編寫readObject方法 274
第89條:對(duì)于實(shí)例控制,枚舉類型優(yōu)先于readResolve 279
第90條:考慮用序列化代理代替序列化實(shí)例 282
附錄 與第2版中條目的對(duì)應(yīng)關(guān)系 286
參考文獻(xiàn) 289