<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、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ### [異常鏈](https://lingcoder.gitee.io/onjava8/#/book/15-Exceptions?id=%e5%bc%82%e5%b8%b8%e9%93%be) 常常會想要在捕獲一個異常后拋出另一個異常,并且希望把原始異常的信息保存下來,這被稱為異常鏈。在 JDK1.4 以前,程序員必須自己編寫代碼來保存原始異常的信息。現在所有 Throwable 的子類在構造器中都可以接受一個 cause(因由)對象作為參數。這個 cause 就用來表示原始異常,這樣通過把原始異常傳遞給新的異常,使得即使在當前位置創建并拋出了新的異常,也能通過這個異常鏈追蹤到異常最初發生的位置。 有趣的是,在 Throwable 的子類中,只有三種基本的異常類提供了帶 cause 參數的構造器。它們是 Error(用于 Java 虛擬機報告系統錯誤)、Exception 以及 RuntimeException。如果要把其他類型的異常鏈接起來,應該使用 initCause() 方法而不是構造器。 下面的例子能讓你在運行時動態地向 DynamicFields 對象添加字段: ~~~ // exceptions/DynamicFields.java // A Class that dynamically adds fields to itself to // demonstrate exception chaining class DynamicFieldsException extends Exception {} public class DynamicFields { private Object[][] fields; public DynamicFields(int initialSize) { fields = new Object[initialSize][2]; for(int i = 0; i < initialSize; i++) fields[i] = new Object[] { null, null }; } @Override public String toString() { StringBuilder result = new StringBuilder(); for(Object[] obj : fields) { result.append(obj[0]); result.append(": "); result.append(obj[1]); result.append("\n"); } return result.toString(); } private int hasField(String id) { for(int i = 0; i < fields.length; i++) if(id.equals(fields[i][0])) return i; return -1; } private int getFieldNumber(String id) throws NoSuchFieldException { int fieldNum = hasField(id); if(fieldNum == -1) throw new NoSuchFieldException(); return fieldNum; } private int makeField(String id) { for(int i = 0; i < fields.length; i++) if(fields[i][0] == null) { fields[i][0] = id; return i; } // No empty fields. Add one: Object[][] tmp = new Object[fields.length + 1][2]; for(int i = 0; i < fields.length; i++) tmp[i] = fields[i]; for(int i = fields.length; i < tmp.length; i++) tmp[i] = new Object[] { null, null }; fields = tmp; // Recursive call with expanded fields: return makeField(id); } public Object getField(String id) throws NoSuchFieldException { return fields[getFieldNumber(id)][1]; } public Object setField(String id, Object value) throws DynamicFieldsException { if(value == null) { // Most exceptions don't have a "cause" // constructor. In these cases you must use // initCause(), available in all // Throwable subclasses. DynamicFieldsException dfe = new DynamicFieldsException(); dfe.initCause(new NullPointerException()); throw dfe; } int fieldNumber = hasField(id); if(fieldNumber == -1) fieldNumber = makeField(id); Object result = null; try { result = getField(id); // Get old value } catch(NoSuchFieldException e) { // Use constructor that takes "cause": throw new RuntimeException(e); } fields[fieldNumber][1] = value; return result; } public static void main(String[] args) { DynamicFields df = new DynamicFields(3); System.out.println(df); try { df.setField("d", "A value for d"); df.setField("number", 47); df.setField("number2", 48); System.out.println(df); df.setField("d", "A new value for d"); df.setField("number3", 11); System.out.println("df: " + df); System.out.println("df.getField(\"d\") : " + df.getField("d")); Object field = df.setField("d", null); // Exception } catch(NoSuchFieldException | DynamicFieldsException e) { e.printStackTrace(System.out); } } } ~~~ 輸出為: ~~~ null: null null: null null: null d: A value for d number: 47 number2: 48 df: d: A new value for d number: 47 number2: 48 number3: 11 df.getField("d") : A new value for d DynamicFieldsException at DynamicFields.setField(DynamicFields.java:65) at DynamicFields. Caused by: java.lang.NullPointerException at DynamicFields.setField(DynamicFields.java:67) ... 1 more ~~~ 每個 DynamicFields 對象都含有一個數組,其元素是“成對的對象”。第一個對象表示字段標識符(一個字符串),第二個表示字段值,值的類型可以是除基本類型外的任意類型。當創建對象的時候,要合理估計一下需要多少字段。當調用 setField() 方法的時候,它將試圖通過標識修改已有字段值,否則就建一個新的字段,并把值放入。如果空間不夠了,將建立一個更長的數組,并把原來數組的元素復制進去。如果你試圖為字段設置一個空值,將拋出一個 DynamicFieldsException 異常,它是通過使用 initCause() 方法把 NullPointerException 對象插入而建立的。 至于返回值,setField() 將用 getField() 方法把此位置的舊值取出,這個操作可能會拋出 NoSuchFieldException 異常。如果客戶端程序員調用了 getField() 方法,那么他就有責任處理這個可能拋出的 NoSuchFieldException 異常,但如果異常是從 setField() 方法里拋出的,這種情況將被視為編程錯誤,所以就使用接受 cause 參數的構造器把 NoSuchFieldException 異常轉換為 RuntimeException 異常。 你會注意到,toString() 方法使用了一個 StringBuilder 來創建其結果。在[字符串](https://lingcoder.gitee.io/onjava8/#/./Strings)這章中你將會了解到更多的關于 StringBuilder 的知識,但是只要你編寫設計循環的 toString() 方法,通常都會想使用它,就像本例一樣。 `main()`方法中的 catch 子句看起來不同 - 它使用相同的子句處理兩種不同類型的異常,這兩種不同的異常通過“或(|)”符號結合起來。 Java 7 的這項功能有助于減少代碼重復,并使你更容易指定要捕獲的確切類型,而不是簡單地捕獲一個基類型。你可以通過這種方式組合多種異常類型。
                  <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>

                              哎呀哎呀视频在线观看