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

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ## Chapter 10. Exceptions(異常) ### Item 76: Strive for failure atomicity(盡力保證故障原子性) After an object throws an exception, it is generally desirable that the object still be in a well-defined, usable state, even if the failure occurred in the midst of performing an operation. This is especially true for checked exceptions, from which the caller is expected to recover. **Generally speaking, a failed method invocation should leave the object in the state that it was in prior to the invocation.** A method with this property is said to be failure-atomic. 在對象拋出異常之后,通常希望對象仍然處于定義良好的可用狀態,即使在執行操作時發生了故障。對于 checked 異常尤其如此,調用者希望從異常中恢復。**一般來說,失敗的方法調用應該使對象處于調用之前的狀態。** 具有此屬性的方法稱為具備故障原子性。 There are several ways to achieve this effect. The simplest is to design immutable objects (Item 17). If an object is immutable, failure atomicity is free. If an operation fails, it may prevent a new object from getting created, but it will never leave an existing object in an inconsistent state, because the state of each object is consistent when it is created and can’t be modified thereafter. 有幾種方式可以達到這種效果。最簡單的方法是設計不可變對象([Item-17](/Chapter-4/Chapter-4-Item-17-Minimize-mutability.md))。如果對象是不可變的,則故障原子性是必然的。如果一個操作失敗,它可能會阻止創建一個新對象,但是它不會讓一個現有對象處于不一致的狀態,因為每個對象的狀態在創建時是一致的,并且在創建后不能修改。 For methods that operate on mutable objects, the most common way to achieve failure atomicity is to check parameters for validity before performing the operation (Item 49). This causes most exceptions to get thrown before object modification commences. For example, consider the Stack.pop method in Item 7: 對于操作可變對象的方法,實現故障原子性的最常見方法是在執行操作之前檢查參數的有效性([Item-49](/Chapter-8/Chapter-8-Item-49-Check-parameters-for-validity.md))。這使得大多數異常在對象修改開始之前被拋出。例如,考慮 `Stack.pop` 方法([Item-7](/Chapter-2/Chapter-2-Item-7-Eliminate-obsolete-object-references.md)): ``` public Object pop() { if (size == 0) throw new EmptyStackException(); Object result = elements[--size]; elements[size] = null; // Eliminate obsolete reference return result; } ``` If the initial size check were eliminated, the method would still throw an exception when it attempted to pop an element from an empty stack. It would, however, leave the size field in an inconsistent (negative) state, causing any future method invocations on the object to fail. Additionally, the ArrayIndexOutOfBoundsException thrown by the pop method would be inappropriate to the abstraction (Item 73). 如果取消了初始大小檢查,當該方法試圖從空堆棧中彈出元素時,仍然會拋出異常。但是,這會使 size 字段處于不一致的(負值)狀態,導致以后該對象的任何方法調用都會失敗。此外,pop 方法拋出的 ArrayIndexOutOfBoundsException 也不適于高層抽象解釋([Item-73](/Chapter-10/Chapter-10-Item-73-Throw-exceptions-appropriate-to-the-abstraction.md))。 A closely related approach to achieving failure atomicity is to order the computation so that any part that may fail takes place before any part that modifies the object. This approach is a natural extension of the previous one when arguments cannot be checked without performing a part of the computation. For example, consider the case of TreeMap, whose elements are sorted according to some ordering. In order to add an element to a TreeMap, the element must be of a type that can be compared using the TreeMap’s ordering. Attempting to add an incorrectly typed element will naturally fail with a ClassCastException as a result of searching for the element in the tree, before the tree has been modified in any way. 實現故障原子性的另一種方式是對計算進行排序,以便可能發生故障的部分都先于修改對象的部分發生。當執行某部分計算才能檢查參數時,這種方法是前一種方法的自然擴展。例如,考慮 TreeMap 的情況,它的元素按照一定的順序排序。為了向 TreeMap 中添加元素,元素的類型必須能夠使用 TreeMap 的順序進行比較。在以任何方式修改「樹」之前,由于在「樹」中搜索元素,試圖添加類型不正確的元素自然會失敗,并導致 ClassCastException 異常。 A third approach to achieving failure atomicity is to perform the operation on a temporary copy of the object and to replace the contents of the object with the temporary copy once the operation is complete. This approach occurs naturally when the computation can be performed more quickly once the data has been stored in a temporary data structure. For example, some sorting functions copy their input list into an array prior to sorting to reduce the cost of accessing elements in the inner loop of the sort. This is done for performance, but as an added benefit, it ensures that the input list will be untouched if the sort fails. 實現故障原子性的第三種方法是以對象的臨時副本執行操作,并在操作完成后用臨時副本替換對象的內容。當數據存儲在臨時數據結構中后,計算過程會更加迅速,這種辦法就是很自然的。例如,一些排序函數在排序之前將其輸入 list 復制到數組中,以降低訪問排序內循環中的元素的成本。這樣做是為了提高性能,但是作為一個額外的好處,它確保如果排序失敗,輸入 list 將保持不變。 A last and far less common approach to achieving failure atomicity is to write recovery code that intercepts a failure that occurs in the midst of an operation, and causes the object to roll back its state to the point before the operation began. This approach is used mainly for durable (disk-based) data structures. 實現故障原子性的最后一種不太常見的方法是編寫恢復代碼,攔截在操作過程中發生的故障,并使對象回滾到操作開始之前的狀態。這種方法主要用于持久的(基于磁盤的)數據結構。 While failure atomicity is generally desirable, it is not always achievable. For example, if two threads attempt to modify the same object concurrently without proper synchronization, the object may be left in an inconsistent state. It would therefore be wrong to assume that an object was still usable after catching a ConcurrentModificationException. Errors are unrecoverable, so you need not even attempt to preserve failure atomicity when throwing AssertionError. 雖然故障原子性通常是可取的,但它并不總是可以實現的。例如,如果兩個線程試圖在沒有適當同步的情況下并發地修改同一個對象,那么該對象可能會處于不一致的狀態。因此,如果假定在捕捉到 ConcurrentModificationException 之后對象仍然可用,那就錯了。該錯誤是不可恢復的,所以在拋出 AssertionError 時,你甚至不需要嘗試保存故障原子性。 Even where failure atomicity is possible, it is not always desirable. For some operations, it would significantly increase the cost or complexity. That said, it is often both free and easy to achieve failure atomicity once you’re aware of the issue. 即使在可以實現故障原子性的情況下,也并不總是可取的。對于某些操作,它將顯著增加成本或復雜性。也就是說,一旦意識到這個問題,就可以輕松地實現故障原子性。 In summary, as a rule, any generated exception that is part of a method’s specification should leave the object in the same state it was in prior to the method invocation. Where this rule is violated, the API documentation should clearly indicate what state the object will be left in. Unfortunately, plenty of existing API documentation fails to live up to this ideal. 總之,作為規則,也作為方法規范的一部分,生成的任何異常都應該使對象保持在方法調用之前的狀態。如果違反了這條規則,API 文檔應該清楚地指出對象將處于什么狀態。不幸的是,許多現有的 API 文檔都沒有做到。 --- **[Back to contents of the chapter(返回章節目錄)](/Chapter-10/Chapter-10-Introduction.md)** - **Previous Item(上一條目):[Item 75: Include failure capture information in detail messages(異常詳細消息中應包含捕獲失敗的信息)](/Chapter-10/Chapter-10-Item-75-Include-failure-capture-information-in-detail-messages.md)** - **Next Item(下一條目):[Item 77: Don’t ignore exceptions(不要忽略異常)](/Chapter-10/Chapter-10-Item-77-Don’t-ignore-exceptions.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>

                              哎呀哎呀视频在线观看