<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                ## 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)**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看