## Chapter 2. Creating and Destroying Objects(創建和銷毀對象)
### Item 1: Consider static factory methods instead of constructors(考慮以靜態工廠方法代替構造函數)
The traditional way for a class to allow a client to obtain an instance is to provide a public constructor. There is another technique that should be a part of every programmer’s toolkit. A class can provide a public static factory method,which is simply a static method that returns an instance of the class. Here’s a simple example from Boolean (the boxed primitive class for boolean). This method translates a boolean primitive value into a Boolean object reference:
客戶端獲得實例的傳統方式是由類提供一個公共構造函數。還有一種技術應該成為每個程序員技能樹的一部分。一個類可以提供公共靜態工廠方法,它只是一個返回類實例的靜態方法。下面是一個來自 Boolean (boolean 的包裝類)的簡單示例。該方法將 boolean 基本類型轉換為 Boolean 對象的引用:
```
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
```
Note that a static factory method is not the same as the Factory Method pattern from Design Patterns [Gamma95]. The static factory method described in this item has no direct equivalent in Design Patterns.
要注意的是靜態工廠方法與來自設計模式的工廠方法模式不同 [Gamma95]。本條目中描述的靜態工廠方法在設計模式中沒有直接等價的方法。
A class can provide its clients with static factory methods instead of, or in addition to, public constructors. Providing a static factory method instead of a public constructor has both advantages and disadvantages.
除了公共構造函數,一個類還可以通過靜態工廠方法提供它的客戶端。使用靜態工廠方法而不是公共構造函數的方式既有優點也有缺點。
**One advantage of static factory methods is that, unlike constructors, they have names.** If the parameters to a constructor do not, in and of themselves, describe the object being returned, a static factory with a well-chosen name is easier to use and the resulting client code easier to read. For example, the constructor BigInteger(int, int, Random), which returns a BigInteger that is probably prime, would have been better expressed as a static factory method named BigInteger.probablePrime. (This method was added in Java 4.)
**靜態工廠方法與構造函數相比的第一個優點,靜態工廠方法有確切名稱。** 如果構造函數的參數本身并不能描述返回的對象,那么具有確切名稱的靜態工廠則更容易使用,生成的客戶端代碼也更容易閱讀。例如,返回可能為素數的 BigInteger 類的構造函數 `BigInteger(int, int, Random)` 最好表示為名為 `BigInteger.probablePrime` 的靜態工廠方法。(這個方法是在 Java 4 中添加的)
A class can have only a single constructor with a given signature. Programmers have been known to get around this restriction by providing two constructors whose parameter lists differ only in the order of their parameter types. This is a really bad idea. The user of such an API will never be able to remember which constructor is which and will end up calling the wrong one by mistake. People reading code that uses these constructors will not know what the code does without referring to the class documentation.
一個類只能有一個具有給定簽名的構造函數。眾所周知,程序員可以通過提供多個構造函數來繞過這個限制,這些構造函數的參數列表僅在參數類型、個數或順序上有所不同。這真是個壞主意。面對這樣一個 API,用戶將永遠無法記住該用哪個構造函數,并且最終會錯誤地調用不適合的構造函數。如果不參考類文檔,閱讀使用這些構造函數代碼的人就不會知道代碼的作用。
**譯注:`two` 不應是確數,應理解為概數,為繞過這個限制提供的構造可以不止兩個;后半句 `...whose parameter lists differ only in the order of their parameter types.` 做了意譯。**
Because they have names, static factory methods don’t share the restriction discussed in the previous paragraph. In cases where a class seems to require multiple constructors with the same signature, replace the constructors with static factory methods and carefully chosen names to highlight their differences.
因為靜態工廠方法有確切名稱,所以它們沒有前一段討論的局限。如果一個類需要具有相同簽名的多個構造函數,那么用靜態工廠方法替換構造函數,并仔細選擇名稱以突出它們的區別。
**A second advantage of static factory methods is that, unlike constructors,they are not required to create a new object each time they’re invoked.** This allows immutable classes (Item 17) to use preconstructed instances, or to cache instances as they’re constructed, and dispense them repeatedly to avoid creating unnecessary duplicate objects. The Boolean.valueOf(boolean) method illustrates this technique: it never creates an object. This technique is similar to the Flyweight pattern [Gamma95]. It can greatly improve performance if equivalent objects are requested often, especially if they are expensive to create.
**靜態工廠方法與構造函數相比的第二個優點,靜態工廠方法不需要在每次調用時創建新對象。** 這允許不可變類([Item-17](/Chapter-4/Chapter-4-Item-17-Minimize-mutability.md))使用預先構造的實例,或在構造實例時緩存實例,并重復分配它們以避免創建不必要的重復對象。`Boolean.valueOf(boolean)` 方法說明了這種技術:它從不創建對象。這種技術類似于享元模式 [Gamma95]。如果經常請求相同的對象,特別是在創建對象的代價很高時,它可以極大地提高性能。
The ability of static factory methods to return the same object from repeated invocations allows classes to maintain strict control over what instances exist at any time. Classes that do this are said to be instance-controlled. There are several reasons to write instance-controlled classes. Instance control allows a class to guarantee that it is a singleton (Item 3) or noninstantiable (Item 4). Also,it allows an immutable value class (Item 17) to make the guarantee that no two equal instances exist: a.equals(b) if and only if a == b. This is the basis of the Flyweight pattern [Gamma95]. Enum types (Item 34) provide this guarantee.
靜態工廠方法在重復調用中能夠返回相同對象,這樣的能力允許類在任何時候都能嚴格控制存在的實例。這樣的類被稱為實例受控的類。編寫實例受控的類有幾個原因。實例控制允許一個類來保證它是一個單例([Item-3](/Chapter-2/Chapter-2-Item-3-Enforce-the-singleton-property-with-a-private-constructor-or-an-enum-type.md))或不可實例化的([Item-4](/Chapter-2/Chapter-2-Item-4-Enforce-noninstantiability-with-a-private-constructor.md))。同時,它允許一個不可變的值類([Item-17](/Chapter-4/Chapter-4-Item-17-Minimize-mutability.md))保證不存在兩個相同的實例:`a.equals(b)` 當且僅當 `a==b` 為 true。這是享元模式的基礎 [Gamma95]。枚舉類型([Item-34](/Chapter-6/Chapter-6-Item-34-Use-enums-instead-of-int-constants.md))提供了這種保證。
**譯注:原文 noninstantiable 應修改為 non-instantiable ,譯為「不可實例化的」**
**A third advantage of static factory methods is that, unlike constructors,they can return an object of any subtype of their return type.** This gives you great flexibility in choosing the class of the returned object.
**靜態工廠方法與構造函數相比的第三個優點,可以通過靜態工廠方法獲取返回類型的任何子類的對象。** 這為選擇返回對象的類提供了很大的靈活性。
One application of this flexibility is that an API can return objects without making their classes public. Hiding implementation classes in this fashion leads to a very compact API. This technique lends itself to interface-based frameworks (Item 20), where interfaces provide natural return types for static factory methods.
這種靈活性的一個應用是 API 可以在不公開其類的情況下返回對象。以這種方式隱藏實現類會形成一個非常緊湊的 API。這種技術適用于基于接口的框架([Item-20](/Chapter-4/Chapter-4-Item-20-Prefer-interfaces-to-abstract-classes.md)),其中接口為靜態工廠方法提供了自然的返回類型。
Prior to Java 8, interfaces couldn’t have static methods. By convention, static factory methods for an interface named Type were put in a noninstantiable companion class (Item 4) named Types. For example, the Java Collections Framework has forty-five utility implementations of its interfaces, providing unmodifiable collections, synchronized collections, and the like. Nearly all of these implementations are exported via static factory methods in one noninstantiable class (java.util.Collections). The classes of the returned objects are all nonpublic.
在 Java 8 之前,接口不能有靜態方法。按照慣例,一個名為 Type 的接口的靜態工廠方法被放在一個名為 Types 的不可實例化的伴隨類([Item-4](/Chapter-2/Chapter-2-Item-4-Enforce-noninstantiability-with-a-private-constructor.md))中。例如,Java 的 Collections 框架有 45 個接口實用工具實現,提供了不可修改的集合、同步集合等。幾乎所有這些實現都是通過一個非實例化類(`java.util.Collections`)中的靜態工廠方法導出的。返回對象的類都是非公共的。
**譯注:原文 noninstantiable 應修改為 non-instantiable ,譯為「不可實例化的」**
The Collections Framework API is much smaller than it would have been had it exported forty-five separate public classes, one for each convenience implementation. It is not just the bulk of the API that is reduced but the conceptual weight: the number and difficulty of the concepts that programmers must master in order to use the API. The programmer knows that the returned object has precisely the API specified by its interface, so there is no need to read additional class documentation for the implementation class. Furthermore, using such a static factory method requires the client to refer to the returned object by interface rather than implementation class, which is generally good practice (Item 64).
Collections 框架 API 比它導出 45 個獨立的公共類要小得多,每個公共類對應一個方便的實現。減少的不僅僅是 API 的數量,還有概念上的減少:程序員為了使用 API 必須掌握的概念的數量和難度。程序員知道返回的對象是由相關的接口精確地指定的,因此不需要為實現類閱讀額外的類文檔。此外,使用這種靜態工廠方法需要客戶端通過接口而不是實現類引用返回的對象,這通常是很好的做法([Item-64](/Chapter-9/Chapter-9-Item-64-Refer-to-objects-by-their-interfaces.md))。
As of(自..起) Java 8, the restriction that interfaces cannot contain static methods was eliminated, so there is typically little reason to provide a noninstantiable companion class for an interface. Many public static members that would have been at home in such a class should instead be put in the interface itself. Note,however, that it may still be necessary to put the bulk of the implementation code behind these static methods in a separate package-private class. This is because Java 8 requires all static members of an interface to be public. Java 9 allows private static methods, but static fields and static member classes are still required to be public.
自 Java 8 起,消除了接口不能包含靜態方法的限制,因此通常沒有理由為接口提供不可實例化的伴隨類。許多公共靜態成員應該放在接口本身中,而不是放在類中。但是,請注意,仍然有必要將這些靜態方法背后的大部分實現代碼放到單獨的包私有類中。這是因為 Java 8 要求接口的所有靜態成員都是公共的。Java 9 允許私有靜態方法,但是靜態字段和靜態成員類仍然需要是公共的。
**A fourth advantage of static factories is that the class of the returned object can vary from call to call as a function of the input parameters.** Any subtype of the declared return type is permissible. The class of the returned object can also vary from release to release.
**靜態工廠的第四個優點是,返回對象的類可以隨調用的不同而變化,作為輸入參數的函數。** 聲明的返回類型的任何子類型都是允許的。返回對象的類也可以因版本而異。
The EnumSet class (Item 36) has no public constructors, only static factories.In the OpenJDK implementation, they return an instance of one of two subclasses, depending on the size of the underlying enum type: if it has sixty-four or fewer elements, as most enum types do, the static factories return a RegularEnumSet instance, which is backed by a single long; if the enum type has sixty-five or more elements, the factories return a JumboEnumSet instance, backed by a long array.
EnumSet 類([Item-36](/Chapter-6/Chapter-6-Item-36-Use-EnumSet-instead-of-bit-fields.md))沒有公共構造函數,只有靜態工廠。在 OpenJDK 實現中,它們返回兩個子類中的一個實例,這取決于底層 enum 類型的大小:如果它有 64 個或更少的元素,就像大多數 enum 類型一樣,靜態工廠返回一個 long 類型的 RegularEnumSet 實例;如果 enum 類型有 65 個或更多的元素,工廠將返回一個由 `long[]` 類型的 JumboEnumSet 實例。
The existence of these two implementation classes is invisible to clients. If RegularEnumSet ceased to offer performance advantages for small enum types, it could be eliminated from a future release with no ill effects. Similarly, a future release could add a third or fourth implementation of EnumSet if it proved beneficial for performance. Clients neither know nor care about the class of the object they get back from the factory; they care only that it is some subclass of EnumSet.
客戶端看不到這兩個實現類的存在。如果 RegularEnumSet 不再為小型 enum 類型提供性能優勢,它可能會在未來的版本中被消除,而不會產生不良影響。類似地,如果事實證明 EnumSet 有益于性能,未來的版本可以添加第三或第四個 EnumSet 實現。客戶端既不知道也不關心從工廠返回的對象的類;它們只關心它是 EnumSet 的某個子類。
**A fifth advantage of static factories is that the class of the returned object need not exist when the class containing the method is written.** Such flexible static factory methods form the basis of service provider frameworks, like the Java Database Connectivity API (JDBC). A service provider framework is a system in which providers implement a service, and the system makes the implementations available to clients, decoupling the clients from the implementations.
**靜態工廠的第五個優點是,當編寫包含方法的類時,返回對象的類不需要存在。** 這種靈活的靜態工廠方法構成了服務提供者框架的基礎,比如 Java 數據庫連接 API(JDBC)。服務提供者框架是一個系統,其中提供者實現一個服務,系統使客戶端可以使用這些實現,從而將客戶端與實現分離。
There are three essential components in a service provider framework: a service interface, which represents an implementation; a provider registration API, which providers use to register implementations; and a service access API,which clients use to obtain instances of the service. The service access API may allow clients to specify criteria for choosing an implementation. In the absence of such criteria, the API returns an instance of a default implementation, or allows the client to cycle through all available implementations. The service access API is the flexible static factory that forms the basis of the service provider framework.
服務提供者框架中有三個基本組件:代表實現的服務接口;提供者注冊 API,提供者使用它來注冊實現,以及服務訪問 API,客戶端使用它來獲取服務的實例。服務訪問 API 允許客戶端指定選擇實現的標準。在沒有這些條件的情況下,API 返回一個默認實現的實例,或者允許客戶端循環使用所有可用的實現。服務訪問 API 是靈活的靜態工廠,它構成了服務提供者框架的基礎。
An optional fourth component of a service provider framework is a service provider interface, which describes a factory object that produce instances of the service interface. In the absence of a service provider interface, implementations must be instantiated reflectively (Item 65). In the case of JDBC, Connection plays the part of the service interface, DriverManager.registerDriver is the provider registration API, DriverManager.getConnection is the service access API, and Driver is the service provider interface.
服務提供者框架的第四個可選組件是服務提供者接口,它描述了產生服務接口實例的工廠對象。在沒有服務提供者接口的情況下,必須以反射的方式實例化實現([Item-65](/Chapter-9/Chapter-9-Item-65-Prefer-interfaces-to-reflection.md))。在 JDBC 中,連接扮演服務接口 DriverManager 的角色。`DriverManager.registerDriver` 是提供商注冊的 API,`DriverManager.getConnection` 是服務訪問 API,驅動程序是服務提供者接口。
There are many variants of the service provider framework pattern. For example, the service access API can return a richer service interface to clients than the one furnished by providers. This is the Bridge pattern [Gamma95]. Dependency injection frameworks (Item 5) can be viewed as powerful service providers. Since Java 6, the platform includes a general-purpose service provider framework, java.util.ServiceLoader, so you needn’t, and generally shouldn’t, write your own (Item 59). JDBC doesn’t use ServiceLoader, as the former predates the latter.
服務提供者框架模式有許多變體。例如,服務訪問 API 可以向客戶端返回比提供者提供的更豐富的服務接口。這是橋接模式 [Gamma95]。依賴注入框架([Item-5](/Chapter-2/Chapter-2-Item-5-Prefer-dependency-injection-to-hardwiring-resources.md))可以看作是強大的服務提供者。由于是 Java 6,該平臺包括一個通用服務提供者框架 `Java.util.ServiceLoader`,所以你不需要,通常也不應該自己寫([Item-59](/Chapter-9/Chapter-9-Item-59-Know-and-use-the-libraries.md))。JDBC 不使用 ServiceLoader,因為前者比后者要早。
**The main limitation of providing only static factory methods is that classes without public or protected constructors cannot be subclassed.** For example, it is impossible to subclass any of the convenience implementation classes in the Collections Framework. Arguably this can be a blessing in disguise because it encourages programmers to use composition instead of inheritance (Item 18), and is required for immutable types (Item 17).
**僅提供靜態工廠方法的主要局限是,沒有公共或受保護構造函數的類不能被子類化。** 例如,不可能在集合框架中子類化任何方便的實現類。這可能是一種因禍得福的做法,因為它鼓勵程序員使用組合而不是繼承([Item-18](/Chapter-4/Chapter-4-Item-18-Favor-composition-over-inheritance.md)),并且對于不可變的類型([Item-17](/Chapter-4/Chapter-4-Item-17-Minimize-mutability.md))是必需的。
**A second shortcoming of static factory methods is that they are hard for programmers to find.** They do not stand out in API documentation in the way that constructors do, so it can be difficult to figure out how to instantiate a class that provides static factory methods instead of constructors. The Javadoc tool may someday draw attention to static factory methods. In the meantime, you can reduce this problem by drawing attention to static factories in class or interface documentation and by adhering to common naming conventions. Here are some common names for static factory methods. This list is far from exhaustive:
**靜態工廠方法的第二個缺點是程序員很難找到它們。** 它們在 API 文檔中不像構造函數那樣引人注目,因此很難弄清楚如何實例化一個只提供靜態工廠方法而沒有構造函數的類。Javadoc 工具總有一天會關注到靜態工廠方法。與此同時,你可以通過在類或接口文檔中對靜態工廠方法多加留意,以及遵守通用命名約定的方式來減少這個困擾。下面是一些靜態工廠方法的常用名稱。這個列表還遠不夠詳盡:
- from—A type-conversion method that takes a single parameter and returns a corresponding instance of this type, for example:
from,一種型轉換方法,該方法接受單個參數并返回該類型的相應實例,例如:
```
Date d = Date.from(instant);
```
- of—An aggregation method that takes multiple parameters and returns an instance of this type that incorporates them, for example:
of,一個聚合方法,它接受多個參數并返回一個包含這些參數的實例,例如:
```
Set<Rank> faceCards = EnumSet.of(JACK, QUEEN, KING);
```
- valueOf—A more verbose alternative to from and of, for example:
valueOf,一種替代 from 和 of 但更冗長的方法,例如:
```
BigInteger prime = BigInteger.valueOf(Integer.MAX_VALUE);
```
- instance or getInstance—Returns an instance that is described by its parameters (if any) but cannot be said to have the same value, for example:
instance 或 getInstance,返回一個實例,該實例由其參數(如果有的話)描述,但不具有相同的值,例如:
```
StackWalker luke = StackWalker.getInstance(options);
```
- create or newInstance—Like instance or getInstance, except that the method guarantees that each call returns a new instance, for example:
create 或 newInstance,與 instance 或 getInstance 類似,只是該方法保證每個調用都返回一個新實例,例如:
```
Object newArray = Array.newInstance(classObject, arrayLen);
```
- getType—Like getInstance, but used if the factory method is in a different class. Type is the type of object returned by the factory method, for example:
getType,類似于 getInstance,但如果工廠方法位于不同的類中,則使用此方法。其類型是工廠方法返回的對象類型,例如:
```
FileStore fs = Files.getFileStore(path);
```
- newType—Like newInstance, but used if the factory method is in a different class. Type is the type of object returned by the factory method, for example:
newType,與 newInstance 類似,但是如果工廠方法在不同的類中使用。類型是工廠方法返回的對象類型,例如:
```
BufferedReader br = Files.newBufferedReader(path);
```
- type—A concise alternative to getType and newType, for example:
type,一個用來替代 getType 和 newType 的比較簡單的方式,例如:
```
List<Complaint> litany = Collections.list(legacyLitany);
```
In summary, static factory methods and public constructors both have their uses, and it pays to understand their relative merits. Often static factories are preferable, so avoid the reflex to provide public constructors without first considering static factories.
總之,靜態工廠方法和公共構造器都有各自的用途,理解它們相比而言的優點是值得的。通常靜態工廠的方式更可取,因此應避免在沒有考慮靜態工廠的情況下就提供公共構造函數。
---
**[Back to contents of the chapter(返回章節目錄)](/Chapter-2/Chapter-2-Introduction.md)**
- **Next Item(下一條目):[Item 2: Consider a builder when faced with many constructor parameters(在面對多個構造函數參數時,請考慮構建器)](/Chapter-2/Chapter-2-Item-2-Consider-a-builder-when-faced-with-many-constructor-parameters.md)**
- Chapter 2. Creating and Destroying Objects(創建和銷毀對象)
- Item 1: Consider static factory methods instead of constructors(考慮以靜態工廠方法代替構造函數)
- Item 2: Consider a builder when faced with many constructor parameters(在面對多個構造函數參數時,請考慮構建器)
- Item 3: Enforce the singleton property with a private constructor or an enum type(使用私有構造函數或枚舉類型實施單例屬性)
- Item 4: Enforce noninstantiability with a private constructor(用私有構造函數實施不可實例化)
- Item 5: Prefer dependency injection to hardwiring resources(依賴注入優于硬連接資源)
- Item 6: Avoid creating unnecessary objects(避免創建不必要的對象)
- Item 7: Eliminate obsolete object references(排除過時的對象引用)
- Item 8: Avoid finalizers and cleaners(避免使用終結器和清除器)
- Item 9: Prefer try with resources to try finally(使用 try-with-resources 優于 try-finally)
- Chapter 3. Methods Common to All Objects(對象的通用方法)
- Item 10: Obey the general contract when overriding equals(覆蓋 equals 方法時應遵守的約定)
- Item 11: Always override hashCode when you override equals(當覆蓋 equals 方法時,總要覆蓋 hashCode 方法)
- Item 12: Always override toString(始終覆蓋 toString 方法)
- Item 13: Override clone judiciously(明智地覆蓋 clone 方法)
- Item 14: Consider implementing Comparable(考慮實現 Comparable 接口)
- Chapter 4. Classes and Interfaces(類和接口)
- Item 15: Minimize the accessibility of classes and members(盡量減少類和成員的可訪問性)
- Item 16: In public classes use accessor methods not public fields(在公共類中,使用訪問器方法,而不是公共字段)
- Item 17: Minimize mutability(減少可變性)
- Item 18: Favor composition over inheritance(優先選擇復合而不是繼承)
- Item 19: Design and document for inheritance or else prohibit it(繼承要設計良好并且具有文檔,否則禁止使用)
- Item 20: Prefer interfaces to abstract classes(接口優于抽象類)
- Item 21: Design interfaces for posterity(為后代設計接口)
- Item 22: Use interfaces only to define types(接口只用于定義類型)
- Item 23: Prefer class hierarchies to tagged classes(類層次結構優于帶標簽的類)
- Item 24: Favor static member classes over nonstatic(靜態成員類優于非靜態成員類)
- Item 25: Limit source files to a single top level class(源文件僅限有單個頂層類)
- Chapter 5. Generics(泛型)
- Item 26: Do not use raw types(不要使用原始類型)
- Item 27: Eliminate unchecked warnings(消除 unchecked 警告)
- Item 28: Prefer lists to arrays(list 優于數組)
- Item 29: Favor generic types(優先使用泛型)
- Item 30: Favor generic methods(優先使用泛型方法)
- Item 31: Use bounded wildcards to increase API flexibility(使用有界通配符增加 API 的靈活性)
- Item 32: Combine generics and varargs judiciously(明智地合用泛型和可變參數)
- Item 33: Consider typesafe heterogeneous containers(考慮類型安全的異構容器)
- Chapter 6. Enums and Annotations(枚舉和注解)
- Item 34: Use enums instead of int constants(用枚舉類型代替 int 常量)
- Item 35: Use instance fields instead of ordinals(使用實例字段替代序數)
- Item 36: Use EnumSet instead of bit fields(用 EnumSet 替代位字段)
- Item 37: Use EnumMap instead of ordinal indexing(使用 EnumMap 替換序數索引)
- Item 38: Emulate extensible enums with interfaces(使用接口模擬可擴展枚舉)
- Item 39: Prefer annotations to naming patterns(注解優于命名模式)
- Item 40: Consistently use the Override annotation(堅持使用 @Override 注解)
- Item 41: Use marker interfaces to define types(使用標記接口定義類型)
- Chapter 7. Lambdas and Streams(λ 表達式和流)
- Item 42: Prefer lambdas to anonymous classes(λ 表達式優于匿名類)
- Item 43: Prefer method references to lambdas(方法引用優于 λ 表達式)
- Item 44: Favor the use of standard functional interfaces(優先使用標準函數式接口)
- Item 45: Use streams judiciously(明智地使用流)
- Item 46: Prefer side effect free functions in streams(在流中使用無副作用的函數)
- Item 47: Prefer Collection to Stream as a return type(優先選擇 Collection 而不是流作為返回類型)
- Item 48: Use caution when making streams parallel(謹慎使用并行流)
- Chapter 8. Methods(方法)
- Item 49: Check parameters for validity(檢查參數的有效性)
- Item 50: Make defensive copies when needed(在需要時制作防御性副本)
- Item 51: Design method signatures carefully(仔細設計方法簽名)
- Item 52: Use overloading judiciously(明智地使用重載)
- Item 53: Use varargs judiciously(明智地使用可變參數)
- Item 54: Return empty collections or arrays, not nulls(返回空集合或數組,而不是 null)
- Item 55: Return optionals judiciously(明智地的返回 Optional)
- Item 56: Write doc comments for all exposed API elements(為所有公開的 API 元素編寫文檔注釋)
- Chapter 9. General Programming(通用程序設計)
- Item 57: Minimize the scope of local variables(將局部變量的作用域最小化)
- Item 58: Prefer for-each loops to traditional for loops(for-each 循環優于傳統的 for 循環)
- Item 59: Know and use the libraries(了解并使用庫)
- Item 60: Avoid float and double if exact answers are required(若需要精確答案就應避免使用 float 和 double 類型)
- Item 61: Prefer primitive types to boxed primitives(基本數據類型優于包裝類)
- Item 62: Avoid strings where other types are more appropriate(其他類型更合適時應避免使用字符串)
- Item 63: Beware the performance of string concatenation(當心字符串連接引起的性能問題)
- Item 64: Refer to objects by their interfaces(通過接口引用對象)
- Item 65: Prefer interfaces to reflection(接口優于反射)
- Item 66: Use native methods judiciously(明智地使用本地方法)
- Item 67: Optimize judiciously(明智地進行優化)
- Item 68: Adhere to generally accepted naming conventions(遵守被廣泛認可的命名約定)
- Chapter 10. Exceptions(異常)
- Item 69: Use exceptions only for exceptional conditions(僅在確有異常條件下使用異常)
- Item 70: Use checked exceptions for recoverable conditions and runtime exceptions for programming errors(對可恢復情況使用 checked 異常,對編程錯誤使用運行時異常)
- Item 71: Avoid unnecessary use of checked exceptions(避免不必要地使用 checked 異常)
- Item 72: Favor the use of standard exceptions(鼓勵復用標準異常)
- Item 73: Throw exceptions appropriate to the abstraction(拋出能用抽象解釋的異常)
- Item 74: Document all exceptions thrown by each method(為每個方法記錄會拋出的所有異常)
- Item 75: Include failure capture information in detail messages(異常詳細消息中應包含捕獲失敗的信息)
- Item 76: Strive for failure atomicity(盡力保證故障原子性)
- Item 77: Don’t ignore exceptions(不要忽略異常)
- Chapter 11. Concurrency(并發)
- Item 78: Synchronize access to shared mutable data(對共享可變數據的同步訪問)
- Item 79: Avoid excessive synchronization(避免過度同步)
- Item 80: Prefer executors, tasks, and streams to threads(Executor、task、流優于直接使用線程)
- Item 81: Prefer concurrency utilities to wait and notify(并發實用工具優于 wait 和 notify)
- Item 82: Document thread safety(文檔應包含線程安全屬性)
- Item 83: Use lazy initialization judiciously(明智地使用延遲初始化)
- Item 84: Don’t depend on the thread scheduler(不要依賴線程調度器)
- Chapter 12. Serialization(序列化)
- Item 85: Prefer alternatives to Java serialization(優先選擇 Java 序列化的替代方案)
- Item 86: Implement Serializable with great caution(非常謹慎地實現 Serializable)
- Item 87: Consider using a custom serialized form(考慮使用自定義序列化形式)
- Item 88: Write readObject methods defensively(防御性地編寫 readObject 方法)
- Item 89: For instance control, prefer enum types to readResolve(對于實例控制,枚舉類型優于 readResolve)
- Item 90: Consider serialization proxies instead of serialized instances(考慮以序列化代理代替序列化實例)