## Chapter 4. Classes and Interfaces(類和接口)
### Item 15: Minimize the accessibility of classes and members(盡量減少類和成員的可訪問性)
The single most important factor that distinguishes a well-designed component from a poorly designed one is the degree to which the component hides its internal data and other implementation details from other components. A welldesigned component hides all its implementation details, cleanly separating its API from its implementation. Components then communicate only through their APIs and are oblivious to each others’ inner workings. This concept, known as information hiding or encapsulation, is a fundamental tenet of software design [Parnas72].
要將設計良好的組件與設計糟糕的組件區別開來,最重要的因素是:隱藏內部數據和其他實現細節的程度。設計良好的組件隱藏了所有實現細節,將 API 與實現完全分離。組件之間只通過它們的 API 進行通信,而不知道彼此的內部工作方式。這個概念被稱為信息隱藏或封裝,是軟件設計的基本原則 [Parnas72]。
Information hiding is important for many reasons, most of which stem from the fact that it decouples the components that comprise a system, allowing them to be developed, tested, optimized, used, understood, and modified in isolation.This speeds up system development because components can be developed in parallel. It eases the burden of maintenance because components can be understood more quickly and debugged or replaced with little fear of harming other components. While information hiding does not, in and of itself, cause good performance, it enables effective performance tuning: once a system is complete and profiling has determined which components are causing performance problems (Item 67), those components can be optimized without affecting the correctness of others. Information hiding increases software reuse because components that aren’t tightly coupled often prove useful in other contexts besides the ones for which they were developed. Finally, information hiding decreases the risk in building large systems because individual components may prove successful even if the system does not.
由于許多原因,信息隱藏是重要的,其中大部分原因源于這樣一個事實:它解耦了組成系統的組件,允許它們被獨立開發、測試、優化、使用、理解和修改。這加快了系統開發進度,因為組件可以并行開發。也減輕了維護的負擔,因為組件可以被更快地理解、調試或替換,而不必擔心會損害其他組件。雖然信息隱藏本身不會獲得良好的性能,但它可以實現有效的性能調優:一旦系統完成,概要分析確定了哪些組件會導致性能問題([Item-67](/Chapter-9/Chapter-9-Item-67-Optimize-judiciously.md)),就可以在不影響其他組件正確性的情況下對這些組件進行優化。信息隱藏增加了軟件的復用性,因為沒有緊密耦合的組件在其他場景中通常被證明是有用的,除了開發它們時所在的場景之外。最后,信息隱藏降低了構建大型系統的風險,因為即使系統沒有成功,單個組件也可能被證明是成功的。
Java has many facilities to aid in information hiding. The access control mechanism [JLS, 6.6] specifies the accessibility of classes, interfaces, and members. The accessibility of an entity is determined by the location of its declaration and by which, if any, of the access modifiers (private,protected, and public) is present on the declaration. Proper use of these modifiers is essential to information hiding.
Java 有許多工具來幫助隱藏信息。訪問控制機制 [JLS, 6.6] 指定了類、接口和成員的可訪問性。實體的可訪問性由其聲明的位置以及聲明中出現的訪問修飾符(private、protected 和 public)決定。正確使用這些修飾符是信息隱藏的關鍵。
The rule of thumb is simple: make each class or member as inaccessible as possible. In other words, use the lowest possible access level consistent with the proper functioning of the software that you are writing.
經驗法則很簡單:讓每個類或成員盡可能不可訪問。換句話說,在不影響軟件正常功能時,使用盡可能低的訪問級別。
For top-level (non-nested) classes and interfaces, there are only two possible access levels: package-private and public. If you declare a top-level class or interface with the public modifier, it will be public; otherwise, it will be package-private. If a top-level class or interface can be made package-private, it should be. By making it package-private, you make it part of the implementation rather than the exported API, and you can modify it, replace it, or eliminate it in a subsequent release without fear of harming existing clients. If you make it public, you are obligated to support it forever to maintain compatibility.
對于頂級(非嵌套)類和接口,只有兩個可能的訪問級別:包私有和公共。如果用 public 修飾符聲明一個頂級類或接口,它將是公共的;否則,它將是包私有的。如果頂級類或接口可以設置為包私有,那么就應該這么做。通過將其設置為包私有,可以使其成為實現的一部分,而不是導出的 API 的一部分,并且可以在后續版本中修改、替換或刪除它,而不必擔心損害現有的客戶端。如果將其公開,就有義務永遠提供支持,以保持兼容性。
If a package-private top-level class or interface is used by only one class,consider making the top-level class a private static nested class of the sole class that uses it (Item 24). This reduces its accessibility from all the classes in its package to the one class that uses it. But it is far more important to reduce the accessibility of a gratuitously public class than of a package-private top-level class: the public class is part of the package’s API, while the package-private top-level class is already part of its implementation.
如果包級私有頂級類或接口只被一個類使用,那么可以考慮:在使用它的這個類中,將頂級類設置為私有靜態嵌套類([Item-24](/Chapter-4/Chapter-4-Item-24-Favor-static-member-classes-over-nonstatic.md))。對于包中的所有類以及使用它的類來說,這降低了它的可訪問性。但是,降低公共類的可訪問性比減少包級私有頂級類的可訪問性重要得多:公共類是包 API 的一部分,而包級私有頂級類已經是實現的一部分。
For members (fields, methods, nested classes, and nested interfaces), there are four possible access levels, listed here in order of increasing accessibility:
對于成員(字段、方法、嵌套類和嵌套接口),有四個可能的訪問級別,這里按可訪問性依次遞增的順序列出:
- **private** —The member is accessible only from the top-level class where it is declared.
**私有**,成員只能從聲明它的頂級類內部訪問。
- **package-private** —The member is accessible from any class in the package where it is declared. Technically known as default access, this is the access level you get if no access modifier is specified (except for interface members,which are public by default).
**包級私有**,成員可以從包中聲明它的任何類訪問。技術上稱為默認訪問,即如果沒有指定訪問修飾符(接口成員除外,默認情況下,接口成員是公共的),就會得到這個訪問級別。
- **protected** —The member is accessible from subclasses of the class where it is declared (subject to a few restrictions [JLS, 6.6.2]) and from any class in the package where it is declared.
**保護**,成員可以通過聲明它的類的子類(會受一些限制 [JLS, 6.6.2])和聲明它的包中的任何類訪問。
- **public** —The member is accessible from anywhere.
**公共**,該成員可以從任何地方訪問。
After carefully designing your class’s public API, your reflex should be to make all other members private. Only if another class in the same package really needs to access a member should you remove the private modifier, making the member package-private. If you find yourself doing this often, you should reexamine the design of your system to see if another decomposition might yield classes that are better decoupled from one another. That said, both private and package-private members are part of a class’s implementation and do not normally impact its exported API. These fields can, however, “leak” into the exported API if the class implements Serializable (Items 86 and 87).
在仔細設計了類的公共 API 之后,你應該本能的使所有成員都是私有的。只有當同一包中的另一個類確實需要訪問一個成員時,你才應該刪除 private 修飾符,使成員變為包級私有。如果你發現自己經常這樣做,那么你應該重新確認系統的設計,看看是否有其他方式能產生更好地相互解耦的類。也就是說,私有成員和包級私有成員都是類實現的一部分,通常不會影響其導出的 API。但是,如果類實現了 Serializable([Item-86](/Chapter-12/Chapter-12-Item-86-Implement-Serializable-with-great-caution.md) 和 [Item-87](/Chapter-12/Chapter-12-Item-87-Consider-using-a-custom-serialized-form.md)),這些字段可能會「泄漏」到導出的 API 中。
For members of public classes, a huge increase in accessibility occurs when the access level goes from package-private to protected. A protected member is part of the class’s exported API and must be supported forever. Also, a protected member of an exported class represents a public commitment to an implementation detail (Item 19). The need for protected members should be relatively rare.
對于公共類的成員來說,當訪問級別從包級私有變為保護時,可訪問性會有很大的提高。保護成員是類導出 API 的一部分,必須永遠支持。此外,導出類的保護成員表示對實現細節的公開承諾([Item-19](/Chapter-4/Chapter-4-Item-19-Design-and-document-for-inheritance-or-else-prohibit-it.md))。需要保護成員的場景應該相對少見。
There is a key rule that restricts your ability to reduce the accessibility of methods. If a method overrides a superclass method, it cannot have a more restrictive access level in the subclass than in the superclass [JLS, 8.4.8.3]. This is necessary to ensure that an instance of the subclass is usable anywhere that an instance of the superclass is usable (the Liskov substitution principle, see Item15). If you violate this rule, the compiler will generate an error message when you try to compile the subclass. A special case of this rule is that if a class implements an interface, all of the class methods that are in the interface must be declared public in the class.
有一個關鍵規則限制了你降低方法的可訪問性。如果一個方法覆蓋了超類方法,那么它在子類中的訪問級別就不能比超類 [JLS, 8.4.8.3] 更嚴格。這對于確保子類的實例在超類的實例可用的任何地方都同樣可用是必要的(Liskov 替換原則,請參閱 [Item-15](/Chapter-4/Chapter-4-Item-15-Minimize-the-accessibility-of-classes-and-members.md))。如果違反此規則,編譯器將在嘗試編譯子類時生成錯誤消息。這個規則的一個特例是,如果一個類實現了一個接口,那么該接口中的所有類方法都必須在類中聲明為 public。
To facilitate testing your code, you may be tempted to make a class, interface,or member more accessible than otherwise necessary. This is fine up to a point. It is acceptable to make a private member of a public class package-private in order to test it, but it is not acceptable to raise the accessibility any higher. In other words, it is not acceptable to make a class, interface, or member a part of a package’s exported API to facilitate testing. Luckily, it isn’t necessary either because tests can be made to run as part of the package being tested, thus gaining access to its package-private elements.
為了便于測試代碼,你可能會試圖使類、接口或成員更容易訪問。這在一定程度上是好的。為了測試,將公共類成員由私有變為包私有是可以接受的,但是進一步提高可訪問性是不可接受的。換句話說,將類、接口或成員作為包導出 API 的一部分以方便測試是不可接受的。幸運的是,也沒有必要這樣做,因為測試可以作為包的一部分運行,從而獲得對包私有元素的訪問權。
**Instance fields of public classes should rarely be public** (Item 16). If an instance field is nonfinal or is a reference to a mutable object, then by making it public, you give up the ability to limit the values that can be stored in the field. This means you give up the ability to enforce invariants involving the field. Also, you give up the ability to take any action when the field is modified, so **classes with public mutable fields are not generally thread-safe.** Even if a field is final and refers to an immutable object, by making it public you give up the flexibility to switch to a new internal data representation in which the field does not exist.
**公共類的實例字段很少采用 public 修飾**([Item-16](/Chapter-4/Chapter-4-Item-16-In-public-classes-use-accessor-methods-not-public-fields.md))。如果實例字段不是 final 的,或者是對可變對象的引用,那么將其公開,你就放棄了限制字段中可以存儲的值的能力。這意味著你放棄了強制包含字段的不可變的能力。此外,你還放棄了在修改字段時采取任何操作的能力,因此 **帶有公共可變字段的類通常不是線程安全的。** 即使一個字段是 final 的,并且引用了一個不可變的對象,通過將其公開,你放棄了切換到一個新的內部數據表示的靈活性,而該字段并不存在。
The same advice applies to static fields, with one exception. You can expose constants via public static final fields, assuming the constants form an integral part of the abstraction provided by the class. By convention, such fields have names consisting of capital letters, with words separated by underscores (Item 68). It is critical that these fields contain either primitive values or references to immutable objects (Item 17). a field containing a reference to a mutable object has all the disadvantages of a nonfinal field. While the reference cannot be modified, the referenced object can be modified—with disastrous results.
同樣的建議也適用于靜態字段,只有一個例外。你可以通過公共靜態 final 字段公開常量,假設這些常量是類提供的抽象的組成部分。按照慣例,這些字段的名稱由大寫字母組成,單詞以下劃線分隔([Item-68](/Chapter-9/Chapter-9-Item-68-Adhere-to-generally-accepted-naming-conventions.md))。重要的是,這些字段要么包含基本數據類型,要么包含對不可變對象的引用([Item-17](/Chapter-4/Chapter-4-Item-17-Minimize-mutability.md))。包含對可變對象的引用的字段具有非 final 字段的所有缺點。雖然引用不能被修改,但是引用的對象可以被修改會導致災難性的后果。
Note that a nonzero-length array is always mutable, so it is wrong for a class to have a public static final array field, or an accessor that returns such a field. If a class has such a field or accessor, clients will be able to modify the contents of the array. This is a frequent source of security holes:
請注意,非零長度的數組總是可變的,因此對于類來說,擁有一個公共靜態 final 數組字段或返回該字段的訪問器是錯誤的。如果一個類具有這樣的字段或訪問器,客戶端將能夠修改數組的內容。這是一個常見的安全漏洞來源:
```
// Potential security hole!
public static final Thing[] VALUES = { ... };
```
Beware of the fact that some IDEs generate accessors that return references to private array fields, resulting in exactly this problem. There are two ways to fix the problem. You can make the public array private and add a public immutable list:
要注意的是,一些 IDE 生成了返回私有數組字段引用的訪問器,這恰恰會導致這個問題。有兩種方法可以解決這個問題。你可以將公共數組設置為私有,并添加一個公共不可變 List:
```
private static final Thing[] PRIVATE_VALUES = { ... };
public static final List<Thing> VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));
```
Alternatively, you can make the array private and add a public method that returns a copy of a private array:
或者,你可以將數組設置為私有,并添加一個返回私有數組副本的公共方法:
```
private static final Thing[] PRIVATE_VALUES = { ... };
public static final Thing[] values() {
return PRIVATE_VALUES.clone();
}
```
To choose between these alternatives, think about what the client is likely to do with the result. Which return type will be more convenient? Which will give better performance?
如何在這些備選方案中進行選擇,請考慮客戶可能會如何處理結果。哪種返回類型更方便?哪種表現會更好?
As of Java 9, there are two additional, implicit access levels introduced as part of the module system. A module is a grouping of packages, like a package is a grouping of classes. A module may explicitly export some of its packages via export declarations in its module declaration (which is by convention contained in a source file named module-info.java). Public and protected members of unexported packages in a module are inaccessible outside the module; within the module, accessibility is unaffected by export declarations. Using the module system allows you to share classes among packages within a module without making them visible to the entire world. Public and protected members of public classes in unexported packages give rise to the two implicit access levels, which are intramodular analogues of the normal public and protected levels. The need for this kind of sharing is relatively rare and can often be eliminated by rearranging the classes within your packages.
對于 Java 9,作為模塊系統的一部分,還引入了另外兩個隱式訪問級別。模塊是包的分組單位,就像包是類的分組單位一樣。模塊可以通過模塊聲明中的導出聲明顯式地導出它的一些包(按照約定包含在名為 `module-info.java` 的源文件中)。模塊中未導出包的公共成員和保護成員在模塊外不可訪問;在模塊中,可訪問性不受導出聲明的影響。通過使用模塊系統,你可以在模塊內的包之間共享類,而不會讓整個世界看到它們。未導出包中的公共類和保護成員產生了兩個隱式訪問級別,它們是正常公共級別和保護級別的類似物。這種共享的需求相對較少,通常可以通過重新安排包中的類來解決。
Unlike the four main access levels, the two module-based levels are largely advisory. If you place a module’s JAR file on your application’s class path instead of its module path, the packages in the module revert to their nonmodular behavior: all of the public and protected members of the packages’ public classes have their normal accessibility, regardless of whether the packages are exported by the module [Reinhold, 1.2]. The one place where the newly introduced access levels are strictly enforced is the JDK itself: the unexported packages in the Java libraries are truly inaccessible outside of their modules.
與四個主要的訪問級別不同,這兩個基于模塊的級別在很大程度上是建議級別。如果將模塊的 JAR 文件放在應用程序的類路徑上,而不是模塊路徑上,模塊中的包將恢復它們的非模塊行為:包的公共類的所有公共成員和保護成員都具有正常的可訪問性,而不管模塊是否導出包 [Reinhold,1.2]。嚴格執行新引入的訪問級別的一個地方是 JDK 本身:Java 庫中未導出的包在其模塊之外確實不可訪問。
Not only is the access protection afforded by modules of limited utility to the typical Java programmer, and largely advisory in nature; in order to take advantage of it, you must group your packages into modules, make all of their dependencies explicit in module declarations, rearrange your source tree, and take special actions to accommodate any access to non-modularized packages from within your modules [Reinhold, 3]. It is too early to say whether modules will achieve widespread use outside of the JDK itself. In the meantime, it seems best to avoid them unless you have a compelling need.
對于典型的 Java 程序員來說,訪問保護不僅是有限實用的模塊所提供的,而且本質上是建議性的;為了利用它,你必須將包以模塊分組,在模塊聲明中顯式地聲明它們的所有依賴項,重新安排源代碼樹,并采取特殊操作以適應從模塊中對非模塊化包的任何訪問 [Reinhold, 3]。現在說模塊能否在 JDK 之外得到廣泛使用還為時過早。與此同時,除非你有迫切的需求,否則最好還是不使用它們。
To summarize, you should reduce accessibility of program elements as much as possible (within reason). After carefully designing a minimal public API, you should prevent any stray classes, interfaces, or members from becoming part of the API. With the exception of public static final fields, which serve as constants,public classes should have no public fields. Ensure that objects referenced by public static final fields are immutable.
總之,你應該盡可能減少程序元素的可訪問性(在合理的范圍內)。在仔細設計了一個最小的公共 API 之后,你應該防止任何游離的類、接口或成員成為 API 的一部分。除了作為常量的公共靜態 final 字段外,public 類應該沒有公共字段。確保公共靜態 final 字段引用的對象是不可變的。
---
**[Back to contents of the chapter(返回章節目錄)](/Chapter-4/Chapter-4-Introduction.md)**
- **Next Item(下一條目):[Item 16: In public classes use accessor methods not public fields(在公共類中,使用訪問器方法,而不是公共字段)](/Chapter-4/Chapter-4-Item-16-In-public-classes-use-accessor-methods-not-public-fields.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(考慮以序列化代理代替序列化實例)