Joshua Bloch
San Jose, California
2017年11月
附:近年来,我在业界的最佳实践方面花费了大量的精力。自20世纪50年代诞生这个行业以来,我们已经自由地重新实现了彼此的API。这个实践对于计算机技术的快速成功至关重要。我始终积极地致力于维护这种自由[CompSci17],并且鼓励你们也加入到这个行列中来。我们的专业要想持续健康地发展,确保重新实现各自API的权利显得尤为重要。
第2版前言
自从我于2001年写了本书的第1版之后,Java平台又发生了很多变化,是该出第2版的时候了。Java 5中最为重要的变化是增加了泛型、枚举类型、注解、自动装箱和for-each
循环。其次是增加了新的并发类库:java.util.concurrent。我和Gilad Bracha一起,有幸带领团队设计了最新的语言特性。我还有幸参加了设计和开发并发类库的团队,这个团队由Doug Lea领导。
Java平台中另一个大的变化在于广泛采用了现代的IDE(Integrated Development Envi-ronment),例如Eclipse、IntelliJ IDEA和NetBeans,以及静态分析工具的IDE,如FindBugs。虽然我还未参与这部分工作,但已经从中受益匪浅,并且很清楚它们对Java开发体验所带来的影响。
2004年,我离开Sun公司到了Google公司工作,但在过去的4年中,我仍然继续参与Java平台的开发,在Google公司和JCP(Java Community Process)的大力帮助下,继续并发和集合API的开发。我还有幸利用Java平台去开发供Google内部使用的类库。现在我了解了作为一名用户的感受。
我在2001年编写第1版的时候,主要目的是与读者分享我的经验,便于让大家避免我所走过的弯路,使大家更容易成功。新版仍然大量采用来自Java平台类库的真实范例。
第1版所带来的反应远远超出了我最大的预期。我在收集所有新的资料以使本书保持最新时,尽可能地保持了资料的真实。毫无疑问,本书的篇幅肯定会增加,从57个条目发展到了78个。我不仅增加了23个条目,并且修改了原来的所有资料,并删去了一些已经过时的条目。在附录中,你可以看到本书中的内容与第1版的内容的对照情况。
在第1版的前言中我说过:Java程序设计语言和它的类库非常有益于代码质量与效率的提高,并且使得用Java进行编码成为一种乐趣。Java 5和Java 6发行版中的变化是好事,这也使Java平台日趋完善。现在这个平台比2001年的要大得多,也复杂得多,但是一旦掌握了使用新特性的模式和习惯用法,它们就会使你的程序变得更完美,使你的工作变得更轻松。我希望第2版能够体现出我对Java平台持续的热情,并将这种热情传递给你,帮助你更加高效和愉快地使用Java平台及其新的特性。
Joshua Bloch
Cupertino, California
2001年4月
◆译者序 ◆
Java从1997年诞生到日趋完善,经过了20多年不断的发展壮大,已经拥有了近千万开发人员。如何编写出更清晰、更正确、更健壮且更易于重用的代码,是大家所追求的目标。本书是经典Jolt获奖作品《Effective Java》的第3版,对上一版内容进行了彻底的更新,涵盖了自2001年第1版之后所引入的Java SE 5和Java SE 6的新特性,以及2008年第2版之后所引入的Java SE 7和Java SE 8以及Java SE 9的新特性。作者探索了新的设计模式和语言习惯用法,介绍了如何充分利用从泛型到枚举、从注解到自动装箱的各种特性,帮助读者更加有效地使用Java编程语言及其基本类库:java.lang、java.util和java.io,以及子包,如java.util.concurrent和java.util.function等。本书的作者Joshua Bloch曾经是Sun公司的杰出工程师和Google公司的首席Java架构师,带领团队设计和实现过无数的Java平台特性,包括JDK 5.0语言增强版和获奖的Java Collections Framework。在本书中,他为我们带来了90条程序员必备的经验法则:针对你每天都会遇到的编程问题提出了最有效、最实用的解决方案。
书中的每一章都包含几个条目,以简洁的形式呈现,自成独立的短文,它们提出了具体的建议、对于Java平台精妙之处的独到见解,并提供优秀的代码范例。每个条目的综合描述和解释都阐明了应该怎么做、不应该怎么做,以及为什么。通过阅读贯穿全书的透彻的技术剖析与完整的示例代码,认真理解并加以实践,必定会从中受益匪浅。书中介绍的示例代码清晰易懂,也可以作为日常工作的参考指南。
读者对象
本书不是针对初学者的,读者至少需要熟悉Java程序设计语言。如果你连equals、toString、hashCode都还不了解的话,建议先去看些优秀的Java入门书籍,之后再来阅读本书。如果你在Java开发方面已经有一定的经验,想更加深入地了解Java编程语言,成为一名更优秀、更高效的Java开发人员,那么,建议你用心研读本书。
内容形式
本书分为12章共90个条目,涵盖了Java 5.0 6.0 7.0 8.0 9.0的种种技术要点。与第2版相比,本书删除了C语言结构的替代一章,增加了Java 7及之后所引入的新特性:Lambda表达式、Stream、Optional类、接口中的默认方法、try-with-resources、
@SafeVarargs注解、Module模块化 。数量上从78个条目发展到了90个,不仅增加了12个条目,并对原来的所有资料都进行了全面的修改,删去了一些已经过时的条目。但是,各章之间并没有严格的前后顺序关系,你可以随意选择感兴趣的章节进行阅读。当然,如果你想马上知道第3版究竟有哪些变化,可以参阅附录。
本书重点讲述了Java 5所引入的全新的泛型、枚举、注解、自动装箱、for-each循环、可变参数、并发机制,还包括对象、类、类库、方法和序列化这些经典主题的全新技术与最佳实践,以及如何避免Java编程语言中常被误解的细微之处:陷阱和缺陷,并重点关注了Java语言本身和最基本的类库(java.lang、java.util)和一些扩展(java.util.concurrent和java.io等)。
主要章节简介
第1章为引言。
第2章阐述何时以及如何创建对象,何时以及如何避免创建对象,如何确保它们能够适时地销毁,以及如何管理对象销毁之前必须进行的各种清除动作。
第3章阐述对于所有对象都通用的方法,你会从中获知对equals、hashCode、toString、clone、finalize以及Comparable.compareTo方法相当深入的分析,从而避免今后在这些问题上再次犯错。
第4章阐述作为Java程序设计语言的核心以及Java语言的基本抽象单元(类和接口)在使用上的一些指导原则,帮助你更好地利用这些元素,设计出更加有用、健壮和灵活的类与接口。
第5章和第6章中分别阐述在Java 1.5发行版本中新增加的泛型(Generic)以及枚举(Enum)和注解(Annotation)的最佳实践,教你如何最大限度地享有这些优势,并使整个过程尽可能地简单化。
第7章专门讨论在Java 8中新增的函数接口(Functional Interface)、Lambda表达式和方法引用(Method Reference),使创建函数对象(Function Object)变得更加容易。接着探讨为处理数据元素的序列提供了类库级别支持的Stream API,以及如何最佳地利用这些机制。
第8章讨论方法设计的几个方面:如何处理参数和返回值,如何设计方法签名,如何为方法编写文档,从而使方法设计在可用性、健壮性和灵活性上有进一步的提升。
第9章主要讨论Java语言的具体细节,讨论了局部变量的处理、控制结构、类库的使用、各种数据类型的用法,以及两种不是由语言本身提供的机制(Reflection和Native Method,反射机制和本地方法)的用法,并讨论了优化和命名惯例。
第10章阐述如何充分发挥异常的优点来提高程序的可读性、可靠性和可维护性,以及减少异常使用不当所带来的负面影响,并提供了一些关于有效使用异常的指导原则。
第11章阐述如何帮助你编写出清晰、正确、文档组织良好的并发程序,比如如何避免过度同步,优先采用Executor Framework、并发集合(Concurrent Collection)、同步器(Synch-ronizer),以及是否需要依赖于线程调度器等。
第12章阐述序列化方面的技术,并且有一项值得特别提及的特性,就是序列化代理(Serialization Proxy)模式,它可以帮助你避免对象序列化的许多缺陷。
举个例子,就序列化技术来讲,HTTP会话状态为什么可以缓存?RMI的异常为什么可以从服务器端传递到客户端?GUI组件为什么可以被发送、保存和恢复呢?是因为它们实现了Serializable接口吗?如果超类没有提供可访问的无参构造器,它的子类可以被序列化吗?当一个实例采用默认的序列化形式,并且给某些域标记为transient,那么当实例反序列化回来后,这些标记为transient域的值各是些什么呢?这些问题如果你现在不能马上回答,或者不能确定,也没有关系,请仔细阅读本书,你将会对它们有更深入与透彻的理解。
技术范围
虽然本书所讨论的是更深层次的Java开发技术,讲述的内容深入,涉及面又相当广泛,但是它并没有涉及图形用户界面编程、企业级API以及移动设备方面的技术,不过在一些条目中会不时地讨论到其他相关的类库。
这是一本分享经验与指引你少走弯路的经典著作,针对如何编写高效、设计优良的程序提出了最实用、最权威的指导方针,是Java开发人员案头上的一本不可或缺的参考书。
本书由我组织进行翻译,并负责本书所有章节的全面审校。参与翻译和审校的还有:杨春花、荣浩、邱庆举、万国辉、陆志平、姜法有、王琳、林仪明、凌家亮、李勇、刘传飞、王建旭、程旭文、罗兴、翟育明、杨征和陈建都。
虽然我们在翻译过程中竭力追求信、达、雅,但限于自身水平,也许仍有不足,还望各位读者不吝指正。关于本书的翻译和翻译时采用的术语以及相关的技术讨论大家可以访问我的博客http:YuLimin.ItEye.com,也可以发邮件到YuLimin @ 163.com与我交流。
在这里,我要感谢在翻译过程中一起讨论并帮助我的朋友们,他们是:满江红开放技术研究组织创始人曹晓钢,Spring中文站创始人杨戈(Yanger),SpringSide创始人肖桦(江南白衣)和来自宝岛台湾的李日贵(jini)、林康司(koji)、林信良(caterpillar),在此再次深表感谢。
最后,感谢华章公司的两位编辑陈佳媛与关敏,她们耐心、细致地审校了全书,使本书得到了极大的改善。赞!
快乐分享,实践出真知,最后,祝大家能够像我一样在阅读中享受本书带来的乐趣!
Read a bit and take it out, then come back read some more.
俞黎敏
2018年10月24日于港珠澳大桥开通之时
◆推荐序 ◆
如果有一个同事这样对你说:我的配偶今天晚上在家里制造了一顿不同寻常的晚餐,你愿意来参加吗?(Spouse of me this night today manufactures the unusual meal in a home. You will join?)这时候你脑子里可能会想到三件事情:第一,满脑子的疑惑;第二,英语肯定不是这位同事的母语;第三,同事是在邀请你参加他的家庭晚宴。
如果你曾经学习过第二种语言,并且尝试过在课堂之外使用这种语言,就该知道有三件事情是必须掌握的:这门语言的结构是怎么样的(语法),如何命名你想谈论的事物(词汇),以及如何以惯用和高效的方式来表达日常事物(用法)。在课堂上大多只涉及前面两点,当你使出浑身解数想让对方明白你的意思时,却常常发现母语人士或当地人对你的表述忍俊不禁。
程序设计语言也是如此。你需要理解语言的核心:它是面向算法的,还是面向函数的或者是面向对象的?你需要知道词汇表:标准类库提供了哪些数据结构、操作和功能?你还需要熟悉如何用习惯和高效的方式来构建代码。关于程序设计语言的书籍通常只涉及前两点,或者只是蜻蜓点水般地介绍一下用法。也许是因为前两点比较容易编写。语法和词汇是语言本身固有的特性,用法则反映了使用这门语言的群体特征。
例如,Java程序设计语言是一门支持单继承的面向对象程序设计语言,在每个方法的内部,它也支持命令式的(面向语句的)编码风格。Java类库提供了对图形显示、网络、分布式计算和安全性的支持。但是,如何把这门语言以最佳的方式运用到实践中呢?
还有一点:程序与口语中的句子以及大多数书籍和杂志都不同,它会随着时间的推移而发生变化。仅仅编写出能够有效地工作并且能够被别人理解的代码往往是不够的,我们还必须把代码组织成易于修改的形式。针对某个任务T可能会有10种不同的编码方法,而在这10种方法中,可能有7种方法是笨拙、低效或者难以理解的。而在剩下的3种编码方法中,哪一种会是最接近任务T的下一年度发行版本的代码呢?
目前有大量的书籍可以供你学习Java程序设计语言的语法,包括《The Java Programming
Language》(作者是Arnold、Gosling和Holmes),以及《The Java Language Specification》(作者是Gosling、Joy和Bracha)。同样,介绍Java程序设计语言相关的类库和API的书籍也不少。
本书将解决你的第三种需求:习惯和高效的用法。作者Joshua Bloch在Sun公司多年来一直从事Java编程语言的扩展、实现和使用的工作;他还大量地阅读了其他人的代码,包括我的代码。他在本书中提出了许多很好的建议,系统地把这些建议组织起来,旨在告诉读者如何更好地构建代码,以便它们能够更好地工作,也便于其他人能够理解这些代码,将来对代码进行修改和改善的时候不至于那么头疼。甚至,你的程序也会因此而变得更加令人愉悦、更加优美和雅致。