Skip to main content

0. 介绍

  本书旨在帮助您有效地使用 Java 编程语言及其基本库:java.lang,java.util 和 java.io 以及如 java.util.concurrent 和 java.util.function 等子包,其他库也会不时讨论。

  这本书由九十项组成,每一个项传达一条规则。这些实践通常被最优秀和经验最丰富的程序员认为是有益的。这些项被松散地分为 11 章,每章涵盖软件设计的一个广泛方面。这本书并不打算让人从头到尾地阅读:每一项或多或少都是独立的。这些项被大量交叉引用,因此你可以很容易地规划你自己的阅读路线。

  自从这本书的上一版出版以来,许多新的特性被添加到了 Java 这个平台。这本书的大部分内容都在某种程度上使用了这些特性。此表给你显示了哪里可以找到关键特性的主要内容:

特性 规则项 发行版本
Lambdas Items 42–44 Java 8
Streams Items 45–48 Java 8
Optionals Item 55 Java 8
Defaultmethodsininterfaces Item 21 Java 8
try-with-resources Item 9 Java 7
@SafeVarargs Item 32 Java 7
Modules Item 15 Java 9

  大多数规则项都用程序示例进行说明。这本书的一个主要特点是它包含了展示许多设计模式和习惯用法的示例代码。在适当的情况下,它们与本领域的标准参考工作交叉引用 [Gamma95]。

  许多规则项包含一个或多个程序示例来说明一些需要避免的实践。这样的例子,有时被称为反模式,被用诸如 "// never do this!" 的注释清楚地标记。在每个情况下,该项都解释了示例不好的原因,并建议使用另一种方法。

  这本书不是针对初学者的:它假设你已经适应了 Java。如果你还没有,请考虑许多很好的介绍性书籍中的一本,比如 Sestoft 的 Java Precisely [Sestoft16]。虽然 Effective Java 被设计为任何一个有工作知识的人都可用,但它也应该对高级程序员提供精神食量。

  这本书中的大多数规则都源于一些基本原则。清晰和简单是最重要的。组件的用户不应该对其行为感到惊讶。组件应该小到不能再小。(正如本书中所使用的,术语组件指任何可重用的软件元素,从单个方法到由多个包组成的复杂框架。)代码应该被重用,而不是被复制。组件之间的依赖应保持在最低限度。错误产生之后应该尽快被检测出来,最好是在编译时。

  虽然本书中的规则并不完全适用,但它们在大多数情况下都符合最佳编程实践。你不应该草率地遵守这些规则,而应该偶尔有理由地违反它们。与大多数其他学科一样,学习编程的艺术包括首先学习规则,然后学习何时打破规则。

  在很大程度上,这本书不是关于性能的。它是关于如何编写清晰、正确、可用、健壮、灵活和可维护的程序的。如果你能做到这一点,获得你需要的性能通常是一件相对简单的事情。(第67项)。一些项目确实讨论了性能问题,其中一些项目提供了性能指标。这些指标,用“在我的机器上”这个词来介绍,充其量应该被视为近似值。

  值得一提的是,我的机器是一台老化的自制电脑,3.5GHz 四核 Intel Core i7-4770K,16 GB DDR3-1866 CL9 RAM,运行Azul'szulu 9.0.0.15 版本的 OpenJDK,位于Microsoft Windows 7 Professional SP1之上(64位)。

  在讨论 Java 编程语言及其库的特性时,有时需要指定特定的版本。为了方便起见,这本书优先使用昵称,而不是正式发行的名字。此表显示发布名称和昵称之间的关系:

官方发行名称 昵称
JDK 1.0.x Java 1.0
JDK 1.1.x Java 1.1
Java 2 Platform, Standard Edition, v1.2 Java 2
Java 2 Platform, Standard Edition, v1.3 Java 3
Java 2 Platform, Standard Edition, v1.4 Java 4
Java 2 Platform, Standard Edition, v5.0 Java 5
Java Platform, Standard Edition 6 Java 6
Java Platform, Standard Edition 7 Java 7
Java Platform, Standard Edition 8 Java 8
Java Platform, Standard Edition 9 Java 9

  这些示例相当完整,但更注重可读性而不是完整性。它们可以自由使用包 java.util 和 java.io 中的类。为了编译示例,您可能必须添加一个或多个导入声明,或其他类似的引用。该书的网站 http://joshbloch.com/effectivejava 包含了每个例子的扩展版本,您可以编译和运行。

  在大多数情况下,本书使用技术术语,因为它们在 Java语言规范,Java SE 第 8 版 [JLS] 中定义。一些术语值得特别提及。语言支持四种类型:接口(包括注释)、类(包括枚举)、数组和原语。前三个是已知的引用类型。类实例和数组是对象,原语值不是。一个类的成员包括其域、方法、成员类和成员接口。一个方法的签名由其名称和其形式参数的类型组成;签名不包括方法的返回类型。

  本书使用的几个术语与 Java 语言规范不同。不像 Java 语言规范,本书使用继承作为子类的同义词。本书不对接口使用术语继承,而是简单地说一个类实现接口或一个接口扩展另一个。为了描述在没有指定时应用的访问级别,本书使用了传统的包-私有,而不是技术上正确的包访问 [JLS, 6.6.1]。

  本书使用了 Java 语言规范中未定义的一些技术术语。 术语 exported API 或 API,指的是程序员对类、接口或包进行访问的类、接口、构造函数、成员和序列化形式。 (术语API,是应用编程接口的简称,优先于原本更好的接口这个术语使用以避免与该名称的语言结构混淆。)使用 API 编写程序的编程人员称为 API 的用户。使用 API 实现的类称为 API 的客户端。

  类、接口、构造函数,成员和序列化形式统称为 API 元素。输出型 API 由可在定义 API 的包之外访问的 API 元素组成。这些是任何客户都可以使用的 API 元素,并且 API 的作者承诺支持。无独有偶,它们也是 Javadoc 实用程序在其默认操作模式下生成文档的元素。简而言之,一个包的输出型 API 包含包中每个公共类或接口的 public 和protected 成员和构造函数。

  在 Java 9 中,模块系统被添加到平台中。如果库使用模块系统,则其输出型 API 是库的模块声明导出的所有包的输出型 API 的并集。