Effective系列丛书
点击这里查看第二章
点击这里查看第三章
Effective Java中文版(原书第3版)
Effective Java, Third Edition
[美]约书亚·布洛克(Joshua Bloch)著
俞黎敏 译
第1章
引言
本书的目标是帮助读者更加有效地使用Java编程语言及其基本类库java.lang、java.util和java.io,以及子包java.util.concurrent和java.util.function等。本书也会时不时地讨论到其他的类库。
本书一共包含90个条目,每个条目讨论一条规则。这些规则反映了最有经验的优秀程序员在实践中常用的一些有益的做法。全书以一种比较松散的方式将这些条目组织成12章,每一章都涉及软件设计的一个主要方面。因此,并不一定需要按部就班地从头到尾阅读本书,因为每个条目都有一定程度的独立性。这些条目相互之间经常交叉引用,因此可以很容易地在书中找到自己需要的内容。
自从本书上一个版本出版之后,Java平台中又增加了许多新特性。本书中大多数条目都以一定的方式用到了这些特性。下表列出了主要特性所在的主要章节或条目。
大多数条目都通过程序示例进行了说明。本书一个突出的特点是,包含了许多用来说明设计模式(Design Pattern)和习惯用法(Idiom)的代码示例。当需要参考设计模式领域的标准参考书[Gamma 95]时,还为这些设计模式和习惯用法提供了交叉引用。
许多条目都包含有一个或多个应该在实践中避免的程序示例。像这样的例子,有时候也叫作“反模式”(Antipattern),在注释中清楚地标注为“//Never do this!”。对于每一种情况,条目中都解释了为什么此例不好,并提出了另外的解决方法。
本书不是针对初学者的,而是假设读者已经熟悉Java编程语言。如果你还不熟悉,请考虑先参阅一本好的Java入门书籍,比如Peter Sestoft的《Java Precisely》[Sestoft16]。本书适用于任何具有实际Java工作经验的程序员,对于高级程序员,也应该能够提供一些发人深思的东西。
本书中大多数规则都源于少数几条基本的原则。清晰性和简洁性最为重要:组件的用户永远也不应该被其行为所迷惑。组件要尽可能小,但又不能太小[本书中使用的术语“组
件”(Component),是指任何可重用的软件元素,从单个方法,到包含多个包的复杂框架,都可以是一个组件]。代码应该被重用,而不是被拷贝。组件之间的依赖性应该尽可能地降到最小。错误应该尽早被检测出来,最好是在编译时就发现并解决。
虽然本书中的规则不会百分之百地适用于任何时刻和任何场合,但是,它们确实体现了绝大多数情况下的最佳编程实践。你不应该盲目地遵循这些规则,但偶尔有了充分理由之后,可以去打破这些规则。同大多数学科一样,学习编程艺术首先要学会基本的规则,然后才能知道什么时候可以打破这些规则。
本书大部分内容都不是讨论性能的,而是关心如何编写出清晰、正确、可用、健壮、灵活和可维护的程序来。如果你能够做到这一点,那么要想获得所需要的性能往往也就水到渠成了(详见第67条)。有些条目确实谈到了性能问题,甚至有的还提供了性能指标。但在提及这些指标的时候,会出现“在我的机器上”这样的话,所以应该把这些指标视同近似值。
有必要提及的是,我的机器是一台过时的家用电脑,CPU是四核Intel Core i7-4770K,主频3.5 GHz,内存DDR3-1866 CL9 16G,在Microsoft Windows 7 Professional SP1(64位)操作系统平台上运行Azul公司发行的OpenJDK:Zulu 9.0.0.15版本。
讨论Java编程语言及其类库特性的时候,有时候必须要指明具体的发行版本。为了简单起见,本书使用了平时大家惯用的昵称,而不是正式的发行名称。下表列出了发行名称与昵称之间的对应关系:
尽管这些示例都很完整,但是它们注重可读性更甚于注重完整性。它们直接使用了java.util和java.io包中的类。为了编译这些示例程序,可能需要在程序中加上一行或者多行这样的import声明,或者其他类似的样板代码。在本书的Web站点http://joshbloch.com/effectivejava,提供了每个示例的完整版本,你可以直接编译和运行这些示例。
本书采用的大部分技术术语都与《The Java Language Specif?ication,Java SE 8 Edition》[JLS]相同。有一些术语则值得特别提及一下。Java语言支持四种类型:接口(包括注释)、类(包括enum)、数组和基本类型。前三种类型通常被称为引用类型(reference type),类实例和数组是对象(object),而基本类型的值则不是对象。类的成员(member)由它的域(f?ield)、方法(method)、成员类(member class)和成员接口(member interface)组成。方法的签名(signature)由它的名称和所有参数类型组成;签名不包括方法的返回类型。
本书也使用了一些与《The Java Language Specif?ication》不同的术语。例如,本书用术语“继承”(inheritance)作为“子类化”(subclassing)的同义词。本书不再使用“接口继承”这种说法,而是简单地说,一个类实现(implement)了一个接口,或者一个接口扩展(extend)了另一个接口。为了描述“在没有指定访问级别的情况下所使用的访问级别”,本书使用了传统的描述性术语“包级私有”(package-private),而不是技术性术语“包级访问”(package access)级别[JLS,6.6.1]。
本书也使用了一些在《The Java Language Specif?ication》中没有定义的术语。术语“导出的API”(exported API),或者简单地说API,是指类、接口、构造器(constructor)、成员和序列化形式(serialized form),程序员通过它们可以访问类、接口或者包。(术语API是Application Programming Interface的简写,这里之所以使用API而不用接口,是为了不与Java语言中的interface类型相混淆。)使用API编写程序的程序员被称为该API的用户(user),在类的实现中使用了API的类被称为该API的客户端(client)。
类、接口、构造器、成员以及序列化形式被统称为API元素(API element)。API由所有可在定义该API的包之外访问的API元素组成。任何客户端都可以使用这些API元素,而API的创建者则负责支持这些API元素。Javadoc工具类在它的默认操作模式下也正是为这些元素生成文档,这绝非偶然。不严格地讲,一个包的导出API是由该包中的每个公有(public)类或者接口中所有公有的或者受保护的(protected)成员和构造器组成。
在Java 9中新增了模块系统(module system)。如果类库使用了模块系统,其API就是类库的模块声明导出的所有包的导出API组合。