## Chapter 9. General Programming(通用程序設計)
### Item 68: Adhere to generally accepted naming conventions(遵守被廣泛認可的命名約定)
The Java platform has a well-established set of naming conventions, many of which are contained in The Java Language Specification [JLS, 6.1]. Loosely speaking, naming conventions fall into two categories: typographical and grammatical.
Java 平臺有一組完善的命名約定,其中許多約定包含在《The Java Language Specification》[JLS, 6.1]。不嚴格地講,命名約定分為兩類:排版和語法。
There are only a handful of typographical naming conventions, covering packages, classes, interfaces, methods, fields, and type variables. You should rarely violate them and never without a very good reason. If an API violates these conventions, it may be difficult to use. If an implementation violates them, it may be difficult to maintain. In both cases, violations have the potential to confuse and irritate other programmers who work with the code and can cause faulty assumptions that lead to errors. The conventions are summarized in this item.
有少量的與排版有關的命名約定,包括包、類、接口、方法、字段和類型變量。如果沒有很好的理由,你不應該違反它們。如果 API 違反了這些約定,那么它可能很難使用。如果實現違反了這些規則,可能很難維護。在這兩種情況下,違規都有可能使其他使用代碼的程序員感到困惑和惱怒,并使他們做出錯誤的假設,從而導致錯誤。本條目概述了各項約定。
Package and module names should be hierarchical with the components separated by periods. Components should consist of lowercase alphabetic characters and, rarely, digits. The name of any package that will be used outside your organization should begin with your organization’s Internet domain name with the components reversed, for example, edu.cmu, com.google, org.eff. The standard libraries and optional packages, whose names begin with java and javax, are exceptions to this rule. Users must not create packages or modules whose names begin with java or javax. Detailed rules for converting Internet domain names to package name prefixes can be found in the JLS [JLS, 6.1].
包名和模塊名應該是分層的,組件之間用句點分隔。組件應該由小寫字母組成,很少使用數字。任何在你的組織外部使用的包,名稱都應該以你的組織的 Internet 域名開頭,并將組件顛倒過來,例如,edu.cmu、com.google、org.eff。以 java 和 javax 開頭的標準庫和可選包是這個規則的例外。用戶不能創建名稱以 java 或 javax 開頭的包或模塊。將 Internet 域名轉換為包名前綴的詳細規則可以在《The Java Language Specification》[JLS, 6.1] 中找到。
The remainder of a package name should consist of one or more components describing the package. Components should be short, generally eight or fewer characters. Meaningful abbreviations are encouraged, for example, util rather than utilities. Acronyms are acceptable, for example, awt. Components should generally consist of a single word or abbreviation.
包名的其余部分應該由描述包的一個或多個組件組成。組件應該很短,通常為 8 個或更少的字符。鼓勵使用有意義的縮寫,例如 util 而不是 utilities。縮寫詞是可以接受的,例如 awt。組件通常應該由一個單詞或縮寫組成。
Many packages have names with just one component in addition to the Internet domain name. Additional components are appropriate for large facilities whose size demands that they be broken up into an informal hierarchy. For example, the javax.util package has a rich hierarchy of packages with names such as java.util.concurrent.atomic. Such packages are known as subpackages, although there is almost no linguistic support for package hierarchies.
除了 Internet 域名之外,許多包的名稱只有一個組件。附加組件適用于大型工具包,這些工具包的大小要求將其分解為非正式的層次結構。例如 `javax.util` 包具有豐富的包層次結構,包的名稱如 `java.util.concurrent.atomic`。這樣的包稱為子包,盡管 Java 幾乎不支持包層次結構。
Class and interface names, including enum and annotation type names, should consist of one or more words, with the first letter of each word capitalized, for example, List or FutureTask. Abbreviations are to be avoided, except for acronyms and certain common abbreviations like max and min. There is some disagreement as to whether acronyms should be uppercase or have only their first letter capitalized. While some programmers still use uppercase, a strong argument can be made in favor of capitalizing only the first letter: even if multiple acronyms occur back-to-back, you can still tell where one word starts and the next word ends. Which class name would you rather see, HTTPURL or HttpUrl?
類和接口名稱,包括枚舉和注釋類型名稱,應該由一個或多個單詞組成,每個單詞的首字母大寫,例如 List 或 FutureTask。除了縮略語和某些常見的縮略語,如 max 和 min,縮略語應該避免使用。縮略語應該全部大寫,還是只有首字母大寫,存在一些分歧。雖然有些程序員仍然使用大寫字母,但支持只將第一個字母大寫的理由很充分:即使多個首字母縮寫連續出現,你仍然可以知道一個單詞從哪里開始,下一個單詞從哪里結束。你希望看到哪個類名,HTTPURL 還是 HttpUrl?
Method and field names follow the same typographical conventions as class and interface names, except that the first letter of a method or field name should be lowercase, for example, remove or ensureCapacity. If an acronym occurs as the first word of a method or field name, it should be lowercase.
方法和字段名遵循與類和接口名相同的排版約定,除了方法或字段名的第一個字母應該是小寫,例如 remove 或 ensureCapacity。如果方法或字段名的首字母縮寫出現在第一個單詞中,那么它應該是小寫的。
The sole exception to the previous rule concerns “constant fields,” whose names should consist of one or more uppercase words separated by the underscore character, for example, VALUES or NEGATIVE_INFINITY. A constant field is a static final field whose value is immutable. If a static final field has a primitive type or an immutable reference type (Item 17), then it is a constant field. For example, enum constants are constant fields. If a static final field has a mutable reference type, it can still be a constant field if the referenced object is immutable. Note that constant fields constitute the only recommended use of underscores.
前面規則的唯一例外是「常量字段」,它的名稱應該由一個或多個大寫單詞組成,由下劃線分隔,例如 VALUES 或 NEGATIVE_INFINITY。常量字段是一個靜態的 final 字段,其值是不可變的。如果靜態 final 字段具有基本類型或不可變引用類型(第17項),那么它就是常量字段。例如,枚舉常量是常量字段。如果靜態 final 字段有一個可變的引用類型,那么如果所引用的對象是不可變的,那么它仍然可以是一個常量字段。注意,常量字段是唯一推薦使用下劃線用法的。
Local variable names have similar typographical naming conventions to member names, except that abbreviations are permitted, as are individual characters and short sequences of characters whose meaning depends on the context in which they occur, for example, i, denom, houseNum. Input parameters are a special kind of local variable. They should be named much more carefully than ordinary local variables, as their names are an integral part of their method’s documentation.
局部變量名與成員名具有類似的排版命名約定,但允許使用縮寫,也允許使用單個字符和短字符序列,它們的含義取決于它們出現的上下文,例如 i、denom、houseNum。輸入參數是一種特殊的局部變量。它們的命名應該比普通的局部變量謹慎得多,因為它們的名稱是方法文檔的組成部分。
Type parameter names usually consist of a single letter. Most commonly it is one of these five: T for an arbitrary type, E for the element type of a collection, K and V for the key and value types of a map, and X for an exception. The return type of a function is usually R. A sequence of arbitrary types can be T, U, V or T1, T2, T3.
類型參數名通常由單個字母組成。最常見的是以下五種類型之一:T 表示任意類型,E 表示集合的元素類型,K 和 V 表示 Map 的鍵和值類型,X 表示異常。函數的返回類型通常為 R。任意類型的序列可以是 T、U、V 或 T1、T2、T3。
For quick reference, the following table shows examples of typographical conventions.
為了快速參考,下表顯示了排版約定的示例。
| Identifier Type | Example |
|:-------:|:-------:|
| Package or module | `org.junit.jupiter.api`, `com.google.common.collect` |
| Class or Interface | Stream, FutureTask, LinkedHashMap,HttpClient |
| Method or Field | remove, groupingBy, getCrc |
| Constant Field | MIN_VALUE, NEGATIVE_INFINITY |
| Local Variable | i, denom, houseNum |
| Type Parameter | T, E, K, V, X, R, U, V, T1, T2 |
Grammatical naming conventions are more flexible and more controversial than typographical conventions. There are no grammatical naming conventions to speak of for packages. Instantiable classes, including enum types, are generally named with a singular noun or noun phrase, such as Thread, PriorityQueue, or ChessPiece. Non-instantiable utility classes (Item 4) are often named with a plural noun, such as Collectors or Collections. Interfaces are named like classes, for example, Collection or Comparator, or with an adjective ending in able or ible, for example, Runnable, Iterable, or Accessible. Because annotation types have so many uses, no part of speech predominates. Nouns, verbs, prepositions, and adjectives are all common, for example, BindingAnnotation, Inject, ImplementedBy, or Singleton.
語法命名約定比排版約定更靈活,也更有爭議。包沒有語法命名約定。可實例化的類,包括枚舉類型,通常使用一個或多個名詞短語來命名,例如 Thread、PriorityQueue 或 ChessPiece。不可實例化的實用程序類([Item-4](/Chapter-2/Chapter-2-Item-4-Enforce-noninstantiability-with-a-private-constructor.md))通常使用復數名詞來命名,例如 collector 或 Collections。接口的名稱類似于類,例如集合或比較器,或者以 able 或 ible 結尾的形容詞,例如 Runnable、Iterable 或 Accessible。因為注解類型有很多的用途,所以沒有哪部分占主導地位。名詞、動詞、介詞和形容詞都很常見,例如,BindingAnnotation、Inject、ImplementedBy 或 Singleton。
Methods that perform some action are generally named with a verb or verb phrase (including object), for example, append or drawImage. Methods that return a boolean value usually have names that begin with the word is or, less commonly, has, followed by a noun, noun phrase, or any word or phrase that functions as an adjective, for example, isDigit, isProbablePrime, isEmpty, isEnabled, or hasSiblings.
執行某些操作的方法通常用動詞或動詞短語(包括對象)命名,例如,append 或 drawImage。返回布爾值的方法的名稱通常以單詞 is 或 has(通常很少用)開頭,后面跟一個名詞、一個名詞短語,或者任何用作形容詞的單詞或短語,例如 isDigit、isProbablePrime、isEmpty、isEnabled 或 hasSiblings。
Methods that return a non-boolean function or attribute of the object on which they’re invoked are usually named with a noun, a noun phrase, or a verb phrase beginning with the verb get, for example, size, hashCode, or getTime. There is a vocal contingent that claims that only the third form (beginning with get) is acceptable, but there is little basis for this claim. The first two forms usually lead to more readable code, for example:
返回被調用對象的非布爾函數或屬性的方法通常使用以 get 開頭的名詞、名詞短語或動詞短語來命名,例如 size、hashCode 或 getTime。有一種說法是,只有第三種形式(以 get 開頭)才是可接受的,但這種說法幾乎沒有根據。前兩種形式的代碼通常可讀性更強,例如:
```
if (car.speed() > 2 * SPEED_LIMIT)
generateAudibleAlert("Watch out for cops!");
```
The form beginning with get has its roots in the largely obsolete Java Beans specification, which formed the basis of an early reusable component architecture. There are modern tools that continue to rely on the Beans naming convention, and you should feel free to use it in any code that is to be used in conjunction with these tools. There is also a strong precedent for following this naming convention if a class contains both a setter and a getter for the same attribute. In this case, the two methods are typically named getAttribute and setAttribute.
以 get 開頭的表單起源于基本過時的 Java bean 規范,該規范構成了早期可復用組件體系結構的基礎。有一些現代工具仍然依賴于 bean 命名約定,你應該可以在任何與這些工具一起使用的代碼中隨意使用它。如果類同時包含相同屬性的 setter 和 getter,則遵循這種命名約定也有很好的先例。在本例中,這兩個方法通常被命名為 getAttribute 和 setAttribute。
A few method names deserve special mention. Instance methods that convert the type of an object, returning an independent object of a different type, are often called toType, for example, toString or toArray. Methods that return a view (Item 6) whose type differs from that of the receiving object are often called asType, for example, asList. Methods that return a primitive with the same value as the object on which they’re invoked are often called typeValue, for example, intValue. Common names for static factories include from, of, valueOf, instance, getInstance, newInstance, getType, and newType (Item 1, page 9).
一些方法名稱值得特別注意。轉換對象類型(返回不同類型的獨立對象)的實例方法通常稱為 toType,例如 toString 或 toArray。返回與接收對象類型不同的視圖([Item-6](/Chapter-2/Chapter-2-Item-6-Avoid-creating-unnecessary-objects.md))的方法通常稱為 asType,例如 asList。返回與調用它們的對象具有相同值的基本類型的方法通常稱為類型值,例如 intValue。靜態工廠的常見名稱包括 from、of、valueOf、instance、getInstance、newInstance、getType 和 newType([Item-1](/Chapter-2/Chapter-2-Item-1-Consider-static-factory-methods-instead-of-constructors.md),第 9 頁)。
Grammatical conventions for field names are less well established and less important than those for class, interface, and method names because welldesigned APIs contain few if any exposed fields. Fields of type boolean are often named like boolean accessor methods with the initial is omitted, for example, initialized, composite. Fields of other types are usually named with nouns or noun phrases, such as height, digits, or bodyStyle. Grammatical conventions for local variables are similar to those for fields but even weaker.
字段名的語法約定沒有類、接口和方法名的語法約定建立得好,也不那么重要,因為設計良好的 API 包含很少的公開字段。類型為 boolean 的字段的名稱通常類似于 boolean 訪問器方法,省略了初始值「is」,例如 initialized、composite。其他類型的字段通常用名詞或名詞短語來命名,如 height、digits 和 bodyStyle。局部變量的語法約定類似于字段的語法約定,但要求更少。
To summarize, internalize the standard naming conventions and learn to use them as second nature. The typographical conventions are straightforward and largely unambiguous; the grammatical conventions are more complex and looser. To quote from The Java Language Specification [JLS, 6.1], “These conventions should not be followed slavishly if long-held conventional usage dictates otherwise.” Use common sense.
總之,將標準命名約定內在化,并將其作為第二性征來使用。排版習慣是直接的,而且在很大程度上是明確的;語法慣例更加復雜和松散。引用《The JavaLanguage Specification》[JLS, 6.1] 中的話說,「如果長期以來的傳統用法要求不遵循這些約定,就不應該盲目地遵循這些約定。」,應使用常識判斷。
---
**[Back to contents of the chapter(返回章節目錄)](/Chapter-9/Chapter-9-Introduction.md)**
- **Previous Item(上一條目):[Item 67: Optimize judiciously(明智地進行優化)](/Chapter-9/Chapter-9-Item-67-Optimize-judiciously.md)**
- **Next Item(下一條目):[Chapter 10 Introduction(章節介紹)](/Chapter-10/Chapter-10-Introduction.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(考慮以序列化代理代替序列化實例)