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

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## Chapter 4. Classes and Interfaces(類和接口) ### Item 21: Design interfaces for posterity(為后代設計接口) Prior to Java 8, it was impossible to add methods to interfaces without breaking existing implementations. If you added a new method to an interface, existing implementations would, in general, lack the method, resulting in a compile-time error. In Java 8, the default method construct was added [JLS 9.4], with the intent of allowing the addition of methods to existing interfaces. But adding new methods to existing interfaces is fraught with risk. 在 Java 8 之前,在不破壞現有實現的情況下向接口添加方法是不可能的。如果在接口中添加新方法,通常導致現有的實現出現編譯時錯誤,提示缺少該方法。在 Java 8 中,添加了默認的方法構造 [JLS 9.4],目的是允許向現有接口添加方法。但是向現有接口添加新方法充滿了風險。 The declaration for a default method includes a default implementation that is used by all classes that implement the interface but do not implement the default method. While the addition of default methods to Java makes it possible to add methods to an existing interface, there is no guarantee that these methods will work in all preexisting implementations. Default methods are “injected” into existing implementations without the knowledge or consent of their implementors. Before Java 8, these implementations were written with the tacit understanding that their interfaces would never acquire any new methods. 默認方法的聲明包括一個默認實現,所有實現接口但不實現默認方法的類都使用這個默認實現。雖然 Java 使得向現有接口添加方法成為可能,但不能保證這些方法在所有現有實現中都能工作。默認方法被「注入」到現有的實現中,而無需實現者的知情或同意。在 Java 8 之前,編寫這些實現時都默認它們的接口永遠不會獲得任何新方法。 Many new default methods were added to the core collection interfaces in Java 8, primarily to facilitate the use of lambdas (Chapter 6). The Java libraries’ default methods are high-quality general-purpose implementations, and in most cases, they work fine. **But it is not always possible to write a default method that maintains all invariants of every conceivable implementation.** Java 8 的核心集合接口增加了許多新的默認方法,主要是為了方便 lambda 表達式的使用(Chapter 6)。**但是,并不總是能夠編寫一個默認方法來維護每個實現所有不變性** For example, consider the removeIf method, which was added to the Collection interface in Java 8. This method removes all elements for which a given boolean function (or predicate) returns true. The default implementation is specified to traverse the collection using its iterator, invoking the predicate on each element, and using the iterator’s remove method to remove the elements for which the predicate returns true. Presumably the declaration looks something like this: 例如,考慮在 Java 8 中被添加到集合接口中的 removeIf 方法。該方法刪除了給定的布爾函數(或 predicate)返回 true 的所有元素。指定默認實現,以使用迭代器遍歷集合,在每個元素上調用 predicate,并使用迭代器的 remove 方法刪除 predicate 返回 true 的元素。聲明大概是這樣的: ``` // Default method added to the Collection interface in Java 8 default boolean removeif(predicate<? super e> filter) { objects.requirenonnull(filter); boolean result = false; for (iterator<e> it = iterator(); it.hasnext(); ) { if (filter.test(it.next())) { it.remove(); result = true; } } return result; } ``` This is the best general-purpose implementation one could possibly write for the removeIf method, but sadly, it fails on some real-world Collection implementations. For example, consider org.apache.commons.collections4.collection.SynchronizedCollection. This class, from the Apache Commons library, is similar to the one returned by the static factory Collections.synchronizedCollection in java.util. The Apache version additionally provides the ability to use a client-supplied object for locking, in place of the collection. In other words, it is a wrapper class (Item 18), all of whose methods synchronize on a locking object before delegating to the wrapped collection. 這是為 removeIf 方法編寫的最好的通用實現,但遺憾的是,它在實際使用的一些 Collection 實現中導致了問題。例如,考慮 `org.apache.commons.collections4.collection.SynchronizedCollection`。這個類來自 Apache Commons 庫,類似于 `java.util` 提供的靜態工廠`Collections.synchronizedCollection`。Apache 版本還提供了使用客戶端提供的對象進行鎖定的功能,以代替集合。換句話說,它是一個包裝器類([Item-18](/Chapter-4/Chapter-4-Item-18-Favor-composition-over-inheritance.md)),其所有方法在委托給包裝集合之前同步鎖定對象。 The Apache SynchronizedCollection class is still being actively maintained, but as of this writing, it does not override the removeIf method. If this class is used in conjunction with Java 8, it will therefore inherit the default implementation of removeIf, which does not, indeed cannot, maintain the class’s fundamental promise: to automatically synchronize around each method invocation. The default implementation knows nothing about synchronization and has no access to the field that contains the locking object. If a client calls the removeIf method on a SynchronizedCollection instance in the presence of concurrent modification of the collection by another thread, a ConcurrentModificationException or other unspecified behavior may result. Apache SynchronizedCollection 類仍然得到了積極的維護,但是在編寫本文時,它沒有覆蓋 removeIf 方法。如果這個類與 Java 8 一起使用,那么它將繼承 removeIf 的默認實現,而 removeIf 并不能維護類的基本承諾:自動同步每個方法調用。默認實現對同步一無所知,也無法訪問包含鎖定對象的字段。如果客戶端在 SynchronizedCollection 實例上調用 removeIf 方法,而另一個線程同時修改了集合,那么可能會導致 ConcurrentModificationException 或其他未指定的行為。 In order to prevent this from happening in similar Java platform libraries implementations, such as the package-private class returned by Collections.synchronizedCollection, the JDK maintainers had to override the default removeIf implementation and other methods like it to perform the necessary synchronization before invoking the default implementation. Preexisting collection implementations that were not part of the Java platform did not have the opportunity to make analogous changes in lockstep with the interface change, and some have yet to do so. 為了防止類似的 Java 庫實現(例如 `Collections.synchronizedCollection` 返回的包私有類)中發生這種情況,JDK 維護人員必須覆蓋默認的 removeIf 實現和其他類似的方法,以便在調用默認實現之前執行必要的同步。不屬于 Java 平臺的現有集合實現沒有機會與接口更改同步進行類似的更改,有些實現還沒有這樣做。 **In the presence of default methods, existing implementations of an interface may compile without error or warning but fail at runtime.** While not terribly common, this problem is not an isolated incident either. A handful of the methods added to the collections interfaces in Java 8 are known to be susceptible, and a handful of existing implementations are known to be affected. 在有默認方法的情況下,接口的現有實現可以在沒有錯誤或警告的情況下通過編譯,但是在運行時出錯。雖然這個問題并不常見,但也沒有那么罕見。已知 Java 8 中添加到集合接口的少數方法是易受影響的,會影響到現存的一部分實現。 Using default methods to add new methods to existing interfaces should be avoided unless the need is critical, in which case you should think long and hard about whether an existing interface implementation might be broken by your default method implementation. Default methods are, however, extremely useful for providing standard method implementations when an interface is created, to ease the task of implementing the interface (Item 20). 除非別無他法,否則應該避免使用默認方法向現有接口添加新方法,如果非要這么做,你應該仔細考慮現有接口實現是否可能被默認方法破壞。然而,在創建接口時,默認方法非常有助于提供標準方法實現,以減輕實現接口的任務量([Item-20](/Chapter-4/Chapter-4-Item-20-Prefer-interfaces-to-abstract-classes.md))。 It is also worth noting that default methods were not designed to support removing methods from interfaces or changing the signatures of existing methods. Neither of these interface changes is possible without breaking existing clients. 同樣值得注意的是,默認方法的設計并不支持從接口中刪除方法或更改現有方法的簽名。你不能做出這些更改,除非破壞現有實現。 The moral is clear. Even though default methods are now a part of the Java platform, **it is still of the utmost importance to design interfaces with great care.** While default methods make it possible to add methods to existing interfaces, there is great risk in doing so. If an interface contains a minor flaw, it may irritate its users forever; if an interface is severely deficient, it may doom the API that contains it. 教訓顯而易見。盡管默認方法現在已經是 Java 平臺的一部分,但是謹慎地設計接口仍然是非常重要的。**雖然默認方法使向現有接口添加方法成為可能,但這樣做存在很大風險。** 如果一個接口包含一個小缺陷,它可能會永遠影響它的使用者;如果接口有嚴重缺陷,它可能會毀掉包含它的 API。 Therefore, it is critically important to test each new interface before you release it. Multiple programmers should implement each interface in different ways. At a minimum, you should aim for three diverse implementations. Equally important is to write multiple client programs that use instances of each new interface to perform various tasks. This will go a long way toward ensuring that each interface satisfies all of its intended uses. These steps will allow you to discover flaws in interfaces before they are released, when you can still correct them easily. **While it may be possible to correct some interface flaws after an interface is released, you cannot count on it.** 因此,在發布每個新接口之前對其進行測試非常重要。多個程序員應該以不同的方式測試每個接口。至少,你應該以三種不同的實現為目標。同樣重要的是編寫多個客戶端程序,用這些程序使用每個新接口的實例來執行各種任務。這將大大有助于確保每個接口滿足其所有預期用途。這些步驟將允許你在接口被發布之前發現它們的缺陷,而你仍然可以輕松地糾正它們。**雖然在接口被發布之后可以糾正一些接口缺陷,但是你不能指望這種方式。** --- **[Back to contents of the chapter(返回章節目錄)](/Chapter-4/Chapter-4-Introduction.md)** - **Previous Item(上一條目):[Item 20: Prefer interfaces to abstract classes(接口優于抽象類)](/Chapter-4/Chapter-4-Item-20-Prefer-interfaces-to-abstract-classes.md)** - **Next Item(下一條目):[Item 22: Use interfaces only to define types(接口只用于定義類型)](/Chapter-4/Chapter-4-Item-22-Use-interfaces-only-to-define-types.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>

                              哎呀哎呀视频在线观看