<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>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## Chapter 4. Classes and Interfaces(類和接口) ### Item 17: Minimize mutability(減少可變性) An immutable class is simply a class whose instances cannot be modified. All of the information contained in each instance is fixed for the lifetime of the object,so no changes can ever be observed. The Java platform libraries contain many immutable classes, including String, the boxed primitive classes, and BigInteger and BigDecimal. There are many good reasons for this:Immutable classes are easier to design, implement, and use than mutable classes.They are less prone to error and are more secure. 不可變類是實例不能被修改的類。每個實例中包含的所有信息在對象的生命周期內都是固定的,因此永遠不會觀察到任何更改。Java 庫包含許多不可變的類,包括 String、基本類型的包裝類、BigInteger 和 BigDecimal。這么做有很好的理由:不可變類比可變類更容易設計、實現和使用。它們不太容易出錯,而且更安全。 To make a class immutable, follow these five rules: 要使類不可變,請遵循以下 5 條規則: 1. **Don’t provide methods that modify the object’s state** (known as mutators). **不要提供修改對象狀態的方法**(這類方法也被稱為修改器) 2. **Ensure that the class can’t be extended.** This prevents careless or malicious subclasses from compromising the immutable behavior of the class by behaving as if the object’s state has changed. Preventing subclassing is generally accomplished by making the class final, but there is an alternative that we’ll discuss later. **確保類不能被繼承。** 這可以防止粗心或惡意的通過子類實例對象狀態可改變的方式,損害父類的不可變行為。防止子類化通常用 final 修飾父類,但是還有一種替代方法,我們將在后面討論。 3. **Make all fields final.** This clearly expresses your intent in a manner that is enforced by the system. Also, it is necessary to ensure correct behavior if a reference to a newly created instance is passed from one thread to another without synchronization, as spelled out in the memory model [JLS, 17.5;Goetz06, 16]. **所有字段用 final 修飾。** 這清楚地表達了意圖,并由系統強制執行。同樣,如果在沒有同步的情況下,引用新創建的實例并從一個線程傳遞到另一個線程,那么就有必要確保正確的行為,就像內存模型中描述的那樣 [JLS, 17.5;Goetz06, 16]。 4. **Make all fields private.** This prevents clients from obtaining access to mutable objects referred to by fields and modifying these objects directly.While it is technically permissible for immutable classes to have public final fields containing primitive values or references to immutable objects, it is not recommended because it precludes changing the internal representation in a later release (Items 15 and 16). **所有字段設為私有。** 這將阻止客戶端訪問字段引用的可變對象并直接修改這些對象。雖然在技術上允許不可變類擁有包含基本類型或對不可變對象的引用的公共 final 字段,但不建議這樣做,因為在以后的版本中無法更改內部表示([Item-15](/Chapter-4/Chapter-4-Item-15-Minimize-the-accessibility-of-classes-and-members.md) 和 [Item-16](/Chapter-4/Chapter-4-Item-16-In-public-classes-use-accessor-methods-not-public-fields.md))。 5. **Ensure exclusive access to any mutable components.** If your class has any fields that refer to mutable objects, ensure that clients of the class cannot obtain references to these objects. Never initialize such a field to a client provided object reference or return the field from an accessor. Make defensive copies (Item 50) in constructors, accessors, and readObject methods (Item 88). **確保對任何可變組件的獨占訪問。** 如果你的類有任何引用可變對象的字段,請確保該類的客戶端無法獲得對這些對象的引用。永遠不要向提供對象引用的客戶端初始化這樣的字段,也不要從訪問器返回字段。在構造函數、訪問器和 readObject 方法([Item-88](/Chapter-12/Chapter-12-Item-88-Write-readObject-methods-defensively.md))中創建防御性副本([Item-50](/Chapter-8/Chapter-8-Item-50-Make-defensive-copies-when-needed.md))。 Many of the example classes in previous items are immutable. One such class is PhoneNumber in Item 11, which has accessors for each attribute but no corresponding mutators. Here is a slightly more complex example: 前面條目中的許多示例類都是不可變的。其中一個類是 [Item-11](/Chapter-3/Chapter-3-Item-11-Always-override-hashCode-when-you-override-equals.md) 中的 PhoneNumber,它的每個屬性都有訪問器,但沒有對應的修改器。下面是一個稍微復雜的例子: ``` // Immutable complex number class public final class Complex { private final double re; private final double im; public Complex(double re, double im) { this.re = re; this.im = im; } public double realPart() { return re; } public double imaginaryPart() { return im; } public Complex plus(Complex c) { return new Complex(re + c.re, im + c.im); } public Complex minus(Complex c) { return new Complex(re - c.re, im - c.im); } public Complex times(Complex c) { return new Complex(re * c.re - im * c.im, re * c.im + im * c.re); } public Complex dividedBy(Complex c) { double tmp = c.re * c.re + c.im * c.im; return new Complex((re * c.re + im * c.im) / tmp, (im * c.re - re * c.im) / tmp); } @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Complex)) return false; Complex c = (Complex) o; // See page 47 to find out why we use compare instead of == return Double.compare(c.re, re) == 0 && Double.compare(c.im, im) == 0; } @Override public int hashCode() { return 31 * Double.hashCode(re) + Double.hashCode(im); } @Override public String toString() { return "(" + re + " + " + im + "i)"; } } ``` This class represents a complex number (a number with both real and imaginary parts). In addition to the standard Object methods, it provides accessors for the real and imaginary parts and provides the four basic arithmetic operations: addition, subtraction, multiplication, and division. Notice how the arithmetic operations create and return a new Complex instance rather than modifying this instance. This pattern is known as the functional approach because methods return the result of applying a function to their operand, without modifying it. Contrast it to the procedural or imperative approach in which methods apply a procedure to their operand, causing its state to change.Note that the method names are prepositions (such as plus) rather than verbs (such as add). This emphasizes the fact that methods don’t change the values of the objects. The BigInteger and BigDecimal classes did not obey this naming convention, and it led to many usage errors. 這個類表示一個復數(包含實部和虛部的數)。除了標準的 Object 方法之外,它還為實部和虛部提供訪問器,并提供四種基本的算術運算:加法、減法、乘法和除法。值得注意的是,算術操作創建和返回一個新的 Complex 實例,而不是修改這個實例。這種模式稱為函數式方法,因為方法返回的結果是將函數應用到其操作數,而不是修改它。將其與過程式或命令式方法進行對比,在這種方法中,方法將一個計算過程應用于它們的操作數,從而導致其狀態發生變化。注意,方法名是介詞(如 plus),而不是動詞(如 add)。這強調了這樣一個事實,即方法不會改變對象的值。BigInteger 和 BigDecimal 類不遵守這種命名約定,這導致了許多使用錯誤。 The functional approach may appear unnatural if you’re not familiar with it,but it enables immutability, which has many advantages. **Immutable objects are simple.** An immutable object can be in exactly one state, the state in which it was created. If you make sure that all constructors establish class invariants, then it is guaranteed that these invariants will remain true for all time, with no further effort on your part or on the part of the programmer who uses the class. Mutable objects, on the other hand, can have arbitrarily complex state spaces. If the documentation does not provide a precise description of the state transitions performed by mutator methods, it can be difficult or impossible to use a mutable class reliably. 如果不熟悉函數式方法,那么它可能看起來不自然,但它實現了不變性,這么做有很多優勢。 **不可變對象很簡單。** 不可變對象可以保持它被創建時的狀態。如果能夠確保所有構造函數都建立了類不變量,那么就可以保證這些不變量將一直保持,而無需你或使用類的程序員做進一步的工作。另一方面,可變對象可以具有任意復雜的狀態空間。如果文檔沒有提供由修改器方法執行的狀態轉換的精確描述,那么就很難或不可能可靠地使用可變類。 **Immutable objects are inherently thread-safe; they require no synchronization.** They cannot be corrupted by multiple threads accessing them concurrently. This is far and away the easiest approach to achieve thread safety.Since no thread can ever observe any effect of another thread on an immutable object, **immutable objects can be shared freely.** Immutable classes should therefore encourage clients to reuse existing instances wherever possible. One easy way to do this is to provide public static final constants for commonly used values. For example, the Complex class might provide these constants: **不可變對象本質上是線程安全的;它們不需要同步。** 它們不會因為多線程并發訪問而損壞。這無疑是實現線程安全的最簡單方法。由于任何線程都無法觀察到另一個線程對不可變對象的任何影響,因此 **可以自由共享不可變對象。** 同時,不可變類應該鼓勵客戶端盡可能復用現有的實例。一種簡單的方法是為常用值提供公共靜態 final 常量。例如,Complex 類可能提供以下常量: ``` public static final Complex ZERO = new Complex(0, 0); public static final Complex ONE = new Complex(1, 0); public static final Complex I = new Complex(0, 1); ``` This approach can be taken one step further. An immutable class can provide static factories (Item 1) that cache frequently requested instances to avoid creating new instances when existing ones would do. All the boxed primitive classes and BigInteger do this. Using such static factories causes clients to share instances instead of creating new ones, reducing memory footprint and garbage collection costs. Opting for static factories in place of public constructors when designing a new class gives you the flexibility to add caching later, without modifying clients. 這種方法可以更進一步。不可變類可以提供靜態工廠([Item-1](/Chapter-2/Chapter-2-Item-1-Consider-static-factory-methods-instead-of-constructors.md)),這些工廠緩存經常請求的實例,以避免在現有實例可用時創建新實例。所有包裝類和 BigInteger 都是這樣做的。使用這種靜態工廠會導致客戶端共享實例而不是創建新實例,從而減少內存占用和垃圾收集成本。在設計新類時,選擇靜態工廠而不是公共構造函數,這將使你能夠靈活地在以后添加緩存,而無需修改客戶端。 A consequence of the fact that immutable objects can be shared freely is that you never have to make defensive copies of them (Item 50). In fact, you never have to make any copies at all because the copies would be forever equivalent to the originals. Therefore, you need not and should not provide a clone method or copy constructor (Item 13) on an immutable class. This was not well understood in the early days of the Java platform, so the String class does have a copy constructor, but it should rarely, if ever, be used (Item 6). 不可變對象可以自由共享這一事實的結果之一是,你永遠不需要對它們進行防御性的復制([Item-50](/Chapter-8/Chapter-8-Item-50-Make-defensive-copies-when-needed.md))。事實上,你根本不需要做任何拷貝,因為拷貝將永遠等同于原件。因此,你不需要也不應該在不可變類上提供克隆方法或復制構造函數([Item-13](/Chapter-3/Chapter-3-Item-13-Override-clone-judiciously.md))。這在 Java 平臺的早期并沒有得到很好的理解,因此 String 類確實有一個復制構造函數,但是,即使有,也應該少用([Item-6](/Chapter-2/Chapter-2-Item-6-Avoid-creating-unnecessary-objects.md))。 **Not only can you share immutable objects, but they can share their internals.** For example, the BigInteger class uses a sign-magnitude representation internally. The sign is represented by an int, and the magnitude is represented by an int array. The negate method produces a new BigInteger of like magnitude and opposite sign. It does not need to copy the array even though it is mutable; the newly created BigInteger points to the same internal array as the original. **你不僅可以共享不可變對象,而且可以共享它們的內部實現。** 例如,BigInteger 類在內部使用符號大小來表示。符號由 int 表示,大小由 int 數組表示。negate 方法產生一個新的 BigInteger,大小相同,符號相反。即使數組是可變的,也不需要復制;新創建的 BigInteger 指向與原始數組相同的內部數組。 **Immutable objects make great building blocks for other objects,** whether mutable or immutable. It’s much easier to maintain the invariants of a complex object if you know that its component objects will not change underneath it. A special case of this principle is that immutable objects make great map keys and set elements: you don’t have to worry about their values changing once they’re in the map or set, which would destroy the map or set’s invariants. **不可變對象可以很好的作為其他對象的構建模塊,** 無論是可變的還是不可變的。如果知道復雜對象的組件對象不會在其內部發生更改,那么維護復雜對象的不變性就會容易得多。這個原則的一個具體的例子是,不可變對象很合適作為 Map 的鍵和 Set 的元素:你不必擔心它們的值在 Map 或 Set 中發生變化,從而破壞 Map 或 Set 的不變性。 **Immutable objects provide failure atomicity for free** (Item 76). Their state never changes, so there is no possibility of a temporary inconsistency. **不可變對象自帶提供故障原子性**([Item-76](/Chapter-10/Chapter-10-Item-76-Strive-for-failure-atomicity.md))。他們的狀態從未改變,所以不可能出現暫時的不一致。 **The major disadvantage of immutable classes is that they require a separate object for each distinct value.** Creating these objects can be costly,especially if they are large. For example, suppose that you have a million-bit BigInteger and you want to change its low-order bit: **不可變類的主要缺點是每個不同的值都需要一個單獨的對象。** 創建這些對象的成本可能很高,尤其是對象很大的時候。例如,假設你有一個百萬位的 BigInteger,你想改變它的低階位: ``` BigInteger moby = ...; moby = moby.flipBit(0); ``` The flipBit method creates a new BigInteger instance, also a million bits long, that differs from the original in only one bit. The operation requires time and space proportional to the size of the BigInteger. Contrast this to java.util.BitSet. Like BigInteger, BitSet represents an arbitrarily long sequence of bits, but unlike BigInteger, BitSet is mutable. The BitSet class provides a method that allows you to change the state of a single bit of a million-bit instance in constant time: flipBit 方法創建了一個新的 BigInteger 實例,也有百萬位長,只在一個比特上與原始的不同。該操作需要與 BigInteger 的大小成比例的時間和空間。與 `java.util.BitSet` 形成對比。與 BigInteger 一樣,BitSet 表示任意長的位序列,但與 BigInteger 不同,BitSet 是可變的。BitSet 類提供了一種方法,可以讓你在固定的時間內改變百萬位實例的單個位的狀態: ``` BitSet moby = ...; moby.flip(0); ``` The performance problem is magnified if you perform a multistep operation that generates a new object at every step, eventually discarding all objects except the final result. There are two approaches to coping with this problem. The first is to guess which multistep operations will be commonly required and to provide them as primitives. If a multistep operation is provided as a primitive, the immutable class does not have to create a separate object at each step. Internally,the immutable class can be arbitrarily clever. For example, BigInteger has a package-private mutable “companion class” that it uses to speed up multistep operations such as modular exponentiation. It is much harder to use the mutable companion class than to use BigInteger, for all of the reasons outlined earlier. Luckily, you don’t have to use it: the implementors of BigInteger did the hard work for you. 如果執行多步操作,在每一步生成一個新對象,最終丟棄除最終結果之外的所有對象,那么性能問題就會被放大。有兩種方法可以解決這個問題。第一種方法是猜測通常需要哪些多步操作,并將它們作為基本數據類型提供。如果將多步操作作為基本數據類型提供,則不可變類不必在每個步驟中創建單獨的對象。在內部,不可變類可以任意聰明。例如,BigInteger 有一個包私有的可變「伴隨類」,它使用這個類來加速多步操作,比如模塊化求冪。由于前面列出的所有原因,使用可變伴隨類要比使用 BigInteger 難得多。幸運的是,你不必使用它:BigInteger 的實現者為你做了艱苦的工作。 The package-private mutable companion class approach works fine if you can accurately predict which complex operations clients will want to perform on your immutable class. If not, then your best bet is to provide a public mutable companion class. The main example of this approach in the Java platform libraries is the String class, whose mutable companion is StringBuilder (and its obsolete predecessor, StringBuffer). 如果你能夠準確地預測客戶端希望在不可變類上執行哪些復雜操作,那么包私有可變伴隨類方法就可以很好地工作。如果不是,那么你最好的選擇就是提供一個公共可變伴隨類。這種方法在 Java 庫中的主要示例是 String 類,它的可變伴隨類是 StringBuilder(及其過時的前身 StringBuffer)。 Now that you know how to make an immutable class and you understand the pros and cons of immutability, let’s discuss a few design alternatives. Recall that to guarantee immutability, a class must not permit itself to be subclassed. This can be done by making the class final, but there is another, more flexible alternative. Instead of making an immutable class final, you can make all of its constructors private or package-private and add public static factories in place of the public constructors (Item 1). To make this concrete, here’s how Complex would look if you took this approach: 既然你已經知道了如何創建不可變類,并且了解了不可變性的優缺點,那么讓我們來討論一些設計方案。回想一下,為了保證不變性,類不允許自己被子類化。可以用 final 修飾以達到目的,但是還有另外一個更靈活的選擇,你可以將其所有構造函數變為私有或包私有,并使用公共靜態工廠方法來代替公共的構造函數([Item-1](/Chapter-2/Chapter-2-Item-1-Consider-static-factory-methods-instead-of-constructors.md))。Complex 類采用這種方式修改后如下所示: ``` // Immutable class with static factories instead of constructors public class Complex { private final double re; private final double im; private Complex(double re, double im) { this.re = re; this.im = im; } public static Complex valueOf(double re, double im) { return new Complex(re, im); } ... // Remainder unchanged } ``` This approach is often the best alternative. It is the most flexible because it allows the use of multiple package-private implementation classes. To its clients that reside outside its package, the immutable class is effectively final because it is impossible to extend a class that comes from another package and that lacks a public or protected constructor. Besides allowing the flexibility of multiple implementation classes, this approach makes it possible to tune the performance of the class in subsequent releases by improving the object-caching capabilities of the static factories. 這種方式通常是最好的選擇。它是最靈活的,因為它允許使用多個包私有實現類。對于駐留在包之外的客戶端而言,不可變類實際上是 final 類,因為不可能繼承自另一個包的類,因為它缺少公共或受保護的構造函數。除了允許多實現類的靈活性之外,這種方法還通過改進靜態工廠的對象緩存功能,使得后續版本中調優該類的性能成為可能。 It was not widely understood that immutable classes had to be effectively final when BigInteger and BigDecimal were written, so all of their methods may be overridden. Unfortunately, this could not be corrected after the fact while preserving backward compatibility. If you write a class whose security depends on the immutability of a BigInteger or BigDecimal argument from an untrusted client, you must check to see that the argument is a “real” BigInteger or BigDecimal, rather than an instance of an untrusted subclass. If it is the latter, you must defensively copy it under the assumption that it might be mutable (Item 50): 當編寫 BigInteger 和 BigDecimal 時,不可變類必須是有效的 final 這一點沒有被廣泛理解,因此它們的所有方法都可能被重寫。遺憾的是,在保留向后兼容性的情況下,這個問題無法得到糾正。如果你編寫的類的安全性依賴于來自不受信任客戶端的 BigInteger 或 BigDecimal 參數的不可變性,那么你必須檢查該參數是否是「真正的」BigInteger 或 BigDecimal,而不是不受信任的子類實例。如果是后者,你必須防御性的復制它,假設它可能是可變的([Item-50](/Chapter-8/Chapter-8-Item-50-Make-defensive-copies-when-needed.md)): ``` public static BigInteger safeInstance(BigInteger val) { return val.getClass() == BigInteger.class ? val : new BigInteger(val.toByteArray()); } ``` The list of rules for immutable classes at the beginning of this item says that no methods may modify the object and that all its fields must be final. In fact these rules are a bit stronger than necessary and can be relaxed to improve performance. In truth, no method may produce an externally visible change in the object’s state. However, some immutable classes have one or more nonfinal fields in which they cache the results of expensive computations the first time they are needed. If the same value is requested again, the cached value is returned, saving the cost of recalculation. This trick works precisely because the object is immutable, which guarantees that the computation would yield the same result if it were repeated. 這個條目開頭的不可變類的規則列表指出,沒有方法可以修改對象,它的所有字段必須是 final 的。實際上,這些規則過于嚴格,可以適當放松來提高性能。實際上,任何方法都不能在對象的狀態中產生外部可見的更改。然而,一些不可變類有一個或多個非 final 字段,它們在第一次需要這些字段時,就會在其中緩存昂貴計算的結果。如果再次請求相同的值,則返回緩存的值,從而節省了重新計算的成本。這個技巧之所以有效,是因為對象是不可變的,這就保證了重復計算會產生相同的結果。 For example, PhoneNumber’s hashCode method (Item 11, page 53) computes the hash code the first time it’s invoked and caches it in case it’s invoked again. This technique, an example of lazy initialization (Item 83), is also used by String. 例如,PhoneNumber 的 hashCode 方法([Item-11](/Chapter-3/Chapter-3-Item-11-Always-override-hashCode-when-you-override-equals.md),第 53 頁)在第一次調用時計算哈希代碼,并緩存它,以備再次調用。這個技術是一個延遲初始化的例子([Item-83](/Chapter-11/Chapter-11-Item-83-Use-lazy-initialization-judiciously.md)),String 也使用這個技術。 One caveat should be added concerning serializability. If you choose to have your immutable class implement Serializable and it contains one or more fields that refer to mutable objects, you must provide an explicit readObject or readResolve method, or use the ObjectOutputStream.writeUnshared and ObjectInputStream.readUnshared methods, even if the default serialized form is acceptable. Otherwise an attacker could create a mutable instance of your class. This topic is covered in detail in Item 88. 關于可序列化性,應該提出一個警告。如果你選擇讓不可變類實現 Serializable,并且該類包含一個或多個引用可變對象的字段,那么你必須提供一個顯式的 readObject 或 readResolve 方法,或者使用 ObjectOutputStream.writeUnshared 或 ObjectInputStream.readUnshared 方法,即使默認的序列化形式是可以接受的。否則攻擊者可能創建類的可變實例。[Item-88](/Chapter-12/Chapter-12-Item-88-Write-readObject-methods-defensively.md)詳細討論了這個主題。 To summarize, resist the urge to write a setter for every getter. **Classes should be immutable unless there’s a very good reason to make them mutable.** Immutable classes provide many advantages, and their only disadvantage is the potential for performance problems under certain circumstances. You should always make small value objects, such as PhoneNumber and Complex, immutable. (There are several classes in the Java platform libraries, such as java.util.Date and java.awt.Point, that should have been immutable but aren’t.) You should seriously consider making larger value objects, such as String and BigInteger, immutable as well. You should provide a public mutable companion class for your immutable class only once you’ve confirmed that it’s necessary to achieve satisfactory performance (Item 67). 總而言之,不要急于為每個 getter 都編寫 setter。**類應該是不可變的,除非有很好的理由讓它們可變。** 不可變類提供了許多優點,它們唯一的缺點是在某些情況下可能出現性能問題。你應該始終使小的值對象(如 PhoneNumber 和 Complex)成為不可變的。(Java 庫中有幾個類,比如 `java.util.Date` 和 `java.awt.Point`,應該是不可改變的,但事實并非如此。)也應該認真考慮將較大的值對象(如 String 和 BigInteger)設置為不可變的。只有確認了實現令人滿意的性能是必要的,才應該為不可變類提供一個公共可變伴隨類([Item-67](/Chapter-9/Chapter-9-Item-67-Optimize-judiciously.md))。 There are some classes for which immutability is impractical. **If a class cannot be made immutable, limit its mutability as much as possible.** Reducing the number of states in which an object can exist makes it easier to reason about the object and reduces the likelihood of errors. Therefore, make every field final unless there is a compelling reason to make it nonfinal. Combining the advice of this item with that of Item 15, your natural inclination should be to **declare every field private final unless there’s a good reason to do otherwise.** 對于某些類來說,不變性是不切實際的。**如果一個類不能成為不可變的,那么就盡可能地限制它的可變性。** 減少對象可能存在的狀態數可以更容易地 reason about the object 并減少出錯的可能性。因此,除非有令人信服的理由,否則每個字段都應該用 final 修飾。將本條目的建議與 Item-15 的建議結合起來,你自然會傾向于 **聲明每個字段為私有 final,除非有很好的理由不這樣做。** **Constructors should create fully initialized objects with all of their invariants established.** Don’t provide a public initialization method separate from the constructor or static factory unless there is a compelling reason to do so. Similarly, don’t provide a “reinitialize” method that enables an object to be reused as if it had been constructed with a different initial state. Such methods generally provide little if any performance benefit at the expense of increased complexity. **構造函數應該創建完全初始化的對象,并建立所有的不變量。** 除非有充分的理由,否則不要提供與構造函數或靜態工廠分離的公共初始化方法。類似地,不要提供「重新初始化」的方法,該方法允許復用對象,就好像它是用不同的初始狀態構造的一樣。這些方法通常只提供很少的性能收益,而代價是增加了復雜性。 The CountDownLatch class exemplifies these principles. It is mutable, but its state space is kept intentionally small. You create an instance, use it once, and it’s done: once the countdown latch’s count has reached zero, you may not reuse it. CountDownLatch 類體現了這些原則。它是可變的,但是它的狀態空間故意保持很小。創建一個實例,使用它一次,它就完成了使命:一旦倒計時鎖存器的計數達到零,你可能不會復用它。 A final note should be added concerning the Complex class in this item. This example was meant only to illustrate immutability. It is not an industrial-strength complex number implementation. It uses the standard formulas for complex multiplication and division, which are not correctly rounded and provide poor semantics for complex NaNs and infinities [Kahan91, Smith62, Thomas94]. 關于本條目中 Complex 類的最后一點需要補充的說明。這個例子只是為了說明不變性。它不是一個工業級強度的復數實現。它使用了復雜乘法和除法的標準公式,這些公式沒有被正確地四舍五入,并且為復雜的 NaNs 和 infinities 提供了糟糕的語義 [Kahan91, Smith62, Thomas94]。 --- **[Back to contents of the chapter(返回章節目錄)](/Chapter-4/Chapter-4-Introduction.md)** - **Previous 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)** - **Next Item(下一條目):[Item 18: Favor composition over inheritance(優先選擇復合而不是繼承)](/Chapter-4/Chapter-4-Item-18-Favor-composition-over-inheritance.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>

                              哎呀哎呀视频在线观看