◆译者序 ◆
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.
俞黎敏
【第3版前言】
1997年,Java才面世不久,James Gosling(Java之父)称之为“超级简单的蓝领语言”[Gosling97]。几乎与此同时,Bjarne Stroustrup(C++之父)则将C++称为“多范式语言”(multi-paradigm language),因为“它与那些只支持单一编程方法的程序语言有着天壤之别”[Stroustrup95]。Stroustrup曾发出过这样的警告:
正如大多数刚面世的语言一样,Java的相对简单性,很可能一部分是出于错觉,一部分是因为其尚不完整而导致的结果。随着时间的推移,Java在规模和复杂度方面都会显著增长。到那时,其规模可能呈双倍甚至三倍增长,并产生大量依赖于实现的扩展或者类库[Stroustrup]。
现在,二十年过去了,坦白地说,Gosling和Stroustrup说的都没有错。Java现在果然是既庞大又复杂,许多东西都带有多个抽象,从并发执行,到迭代,再到日期和时间的表示法。
随着Java平台的发展,我的热情有所降温,但我依然钟爱Java。考虑到Java日益增加的规模和复杂度,对于最前沿的最佳实践指导的需求成了重中之重。在本书中,我将不遗余力地为读者提供这样的指导。希望这一版能够在坚持前两个版本的精神的前提下,继续满足读者的最新需求。
简单即美,但要做到大道至简却实属不易。
Joshua Bloch
San Jose, California
附:近年来,我在业界的最佳实践方面花费了大量的精力。自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
San Jose, California
【第1版前言】
1996年,我打点行囊,西行来到了当时的JavaSoft,因为我很清楚那里将会出现奇迹。在这5年间,我是Java平台库的架构师。我设计、实现和维护过许多类库,同时也担任其他一些库的技术顾问。随着Java平台的成熟和壮大,主持这些类库的设计工作是一个人一生中难得的机会。毫不夸张地说,我有幸与一些当代最杰出的软件工程师一起工作。在这个过程中,我学到了许多关于Java程序设计语言的知识——它能够做什么,不能够做什么,以及如何最有效地使用这门语言及其类库。
本书是我的一次尝试,希望与你分享我的经验,你可以因此而吸取我的经验,避免重复我的失败。本书中我借用了Scott Meyers的《Effective C++》一书的格式,该书中包含50个条目,每个条目给出一条用于改进程序和设计的规则。我觉得这种格式非常有效,希望你也有这样的感觉。
在许多例子中,我冒昧地使用了Java平台库中的真实例子来说明相应的条目。在介绍那些做得不是很完美的工作时,我尽量使用我自己编写的代码,但是偶尔我也会使用其他同事的代码。尽管我尽力做得更好一点,但是如果我真的冒犯了他人,我先在这里致以最诚挚的歉意。引用反面例子是出于协作的精神,而不是要羞辱例子中的做法,我希望大家都能够从我们过去的错误经历中得到启发。
尽管本书并不只是针对可重用组件开发人员的,但是过去20多年来我编写此类组件的经历一定会影响这本书。我很自然地会按照可导出API(Application Programming Interface)的方式来思考问题,而且我建议你也这样做。即使你并没有开发可重用的组件,这样的思考方法也将有助于你提升软件的质量。进一步来说,毫无意识地编写可重用组件的情形并不少见:你编写了一些很有用的代码,然后在同伴之间共享,不久之后你就有了很多用户。这时候,你就不能随心所欲地改变API了,并且如果你刚开始编写软件的时候在设计API上付出了较多的努力,那么这时你就会非常庆幸了。
我把焦点放在API的设计上,这对于那些热衷于新兴的轻量级软件开发方法学(比如Extreme Programming,即“极限编程”,简称XP)的读者来说,也许会显得有点不太自然。这些方法学强调编写最简单的、能够工作的程序。如果你正在使用此类的某种程序设计方法,那么你会发现,把焦点放在API设计上对于“重构”(refactoring)过程是多么有益。重构的基本目标是改进系统结构,以及避免代码重复。如果系统的组件没有设计良好的API,要达到这样的目标则是不可能的。
没有一门语言是完美的,但是有些语言非常优秀。我认为Java程序设计语言及其类库非常有益于提高代码质量和工作效率,并使得编码工作成为一种乐趣。我希望本书能够抓住我的热情并传递给你,帮助你更有效地利用Java语言,使工作变得更加愉快。
Joshua Bloch
Cupertino, California