<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、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                {% raw %} # Java 中的異常 原文:http://zetcode.com/lang/java/exceptions/ 在 Java 教程的這一章中,我們將處理異常。 Java 使用異常來處理錯誤。 在執行應用期間,許多事情可能出錯。 磁盤可能已滿,我們無法保存數據。 當我們的應用嘗試連接到站點時,互聯網連接可能會斷開。 用戶將無效數據填充到表單。 這些錯誤可能會使應用崩潰,使其無法響應,并且在某些情況下甚至會損害系統的安全性。 程序員有責任處理可以預期的錯誤。 在 Java 中,我們可以識別三種異常:受檢的異常,非受檢的異常和錯誤。 ## Java 受檢的異常 受檢的異常是可以預期并從中恢復的錯誤情況(無效的用戶輸入,數據庫問題,網絡中斷,文件缺失)。 除`RuntimeException`及其子類之外的`Exception`的所有子類都是受檢的異常。 `IOException`,`SQLException`或`PrinterException`是受檢的異常的示例。 Java 編譯器強制將受檢的異常捕獲或在方法簽名中聲明(使用`throws`關鍵字)。 ## Java 非受檢的異常 非受檢的異常是無法預期和無法恢復的錯誤條件。 它們通常是編程錯誤,無法在運行時處理。 非受檢的異常是`java.lang.RuntimeException`的子類。 `ArithmeticException`,`NullPointerException`或`BufferOverflowException`屬于這組異常。 Java 編譯器不強制執行非受檢的異常。 ## Java 錯誤 錯誤是程序員無法解決的嚴重問題。 例如,應用無法處理硬件或系統故障。 錯誤是`java.lang.Error`類的實例。 錯誤的示例包括`InternalError`,`OutOfMemoryError`,`StackOverflowError`或`AssertionError`。 錯誤和運行時異常通常稱為非受檢的異常。 ## Java `try`,`catch`和`finally` `try`,`catch`和`finally`關鍵字用于處理異常。 `throws`關鍵字在方法聲明中用于指定哪些異常不在方法內處理,而是傳遞給程序的下一個更高級別。 `throw`關鍵字導致拋出已聲明的異常實例。 引發異常后,運行時系統將嘗試查找適當的異常處理器。 調用棧是為處理器搜索的方法的層次結構。 ## Java 非受檢的異常示例 Java 受檢的異常包括`ArrayIndexOutOfBoundsException`,`UnsupportedOperationException`,`NullPointerException`和`InputMismatchException`。 ### `ArrayIndexOutOfBoundsException` 拋出`ArrayIndexOutOfBoundsException`表示已使用非法索引訪問了數組。 索引為負或大于或等于數組的大小。 `com/zetcode/ArrayIndexOutOfBoundsEx.java` ```java package com.zetcode; public class ArrayIndexOutOfBoundsEx { public static void main(String[] args) { int[] n = { 5, 2, 4, 5, 6, 7, 2 }; System.out.format("The last element in the array is %d%n", n[n.length]); } } ``` 上面的程序中有一個錯誤。 我們嘗試訪問一個不存在的元素。 這是編程錯誤。 沒有理由要處理此錯誤:必須固定代碼。 ```java System.out.format("The last element in the array is %d%n", n[n.length]); ``` 數組索引從零開始。 因此,最后一個索引是`n.length - 1`。 ```java $ java ArrayIndexOutOfBoundsEx.java Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 7 out of bounds for length 7 at com.zetcode.ArrayIndexOutOfBoundsEx.main(ArrayIndexOutOfBoundsEx.java:9) ``` 運行系統將拋出`java.lang.ArrayIndexOutOfBoundsException`。 這是非受檢的異常的示例。 ### `UnsupportedOperationException` 拋出`UnsupportedOperationException`,表明不支持所請求的操作。 `com/zetcode/UnsupportedOperationEx.java` ```java package com.zetcode; import java.util.List; public class UnsupportedOperationEx { public static void main(String[] args) { var words = List.of("sky", "blue", "forest", "lake", "river"); words.add("ocean"); System.out.println(words); } } ``` 用`List.of()`工廠方法創建一個不可變列表。 不可變列表不支持`add()`方法; 因此,我們在運行示例時拋出了`UnsupportedOperationException`。 ### `NullPointerException` 當應用嘗試使用具有`null`值的對象引用時,將引發`NullPointerException`。 例如,我們在`null`引用所引用的對象上調用實例方法。 `com/zetcode/NullPointerEx.java` ```java package com.zetcode; import java.util.ArrayList; import java.util.List; public class NullPointerEx { public static void main(String[] args) { List<String> words = new ArrayList<>() {{ add("sky"); add("blue"); add("cloud"); add(null); add("ocean"); }}; words.forEach(word -> { System.out.printf("The %s word has %d letters%n", word, word.length()); }); } } ``` 該示例遍歷字符串列表,并確定每個字符串的長度。 在`null`值上調用`length()`會導致`NullPointerException`。 為了解決這個問題,我們可以在調用`length()`之前從檢查列表中刪除`null`值的所有`null`值。 ### `InputMismatchException` `Scanner`類拋出`InputMismatchException`,以指示檢索到的令牌與預期類型的??模式不匹配。 此異常是非受檢的異常的示例。 編譯器不強制我們處理此異常。 `com/zetcode/InputMismatchEx.java` ```java package com.zetcode; import java.util.InputMismatchException; import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; public class InputMismatchEx { public static void main(String[] args) { System.out.print("Enter an integer: "); try { Scanner sc = new Scanner(System.in); int x = sc.nextInt(); System.out.println(x); } catch (InputMismatchException e) { Logger.getLogger(InputMismatchEx.class.getName()).log(Level.SEVERE, e.getMessage(), e); } } ``` 容易出錯的代碼位于`try`塊中。 如果引發異常,則代碼跳至`catch`塊。 引發的異常類必須與`catch`關鍵字后面的異常匹配。 ```java try { Scanner sc = new Scanner(System.in); int x = sc.nextInt(); System.out.println(x); } ``` `try`關鍵字定義了可能引發異常的語句塊。 ```java } catch (InputMismatchException e) { Logger.getLogger(InputMismatchEx.class.getName()).log(Level.SEVERE, e.getMessage(), e); } ``` 異常在`catch`塊中處理。 我們使用`Logger`類記錄錯誤。 ## 受檢的異常 Java 受檢的異常包括`SQLException`,`IOException`或`ParseException`。 ### `SQLException` 使用數據庫時發生`SQLException`。 `com/zetcode/MySqlVersionEx.java` ```java package com.zetcode; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.logging.Level; import java.util.logging.Logger; public class MySqlVersionEx { public static void main(String[] args) { Connection con = null; Statement st = null; ResultSet rs = null; String url = "jdbc:mysql://localhost:3306/testdb?useSsl=false"; String user = "testuser"; String password = "test623"; try { con = DriverManager.getConnection(url, user, password); st = con.createStatement(); rs = st.executeQuery("SELECT VERSION()"); if (rs.next()) { System.out.println(rs.getString(1)); } } catch (SQLException ex) { Logger lgr = Logger.getLogger(MySqlVersionEx.class.getName()); lgr.log(Level.SEVERE, ex.getMessage(), ex); } finally { if (rs != null) { try { rs.close(); } catch (SQLException ex) { Logger lgr = Logger.getLogger(MySqlVersionEx.class.getName()); lgr.log(Level.SEVERE, ex.getMessage(), ex); } } if (st != null) { try { st.close(); } catch (SQLException ex) { Logger lgr = Logger.getLogger(MySqlVersionEx.class.getName()); lgr.log(Level.SEVERE, ex.getMessage(), ex); } } if (con != null) { try { con.close(); } catch (SQLException ex) { Logger lgr = Logger.getLogger(MySqlVersionEx.class.getName()); lgr.log(Level.SEVERE, ex.getMessage(), ex); } } } } } ``` 該示例連接到 MySQL 數據庫并找出數據庫系統的版本。 連接數據庫很容易出錯。 ```java try { con = DriverManager.getConnection(url, user, password); st = con.createStatement(); rs = st.executeQuery("SELECT VERSION()"); if (rs.next()) { System.out.println(rs.getString(1)); } } ``` 可能導致錯誤的代碼位于`try`塊中。 ```java } catch (SQLException ex) { Logger lgr = Logger.getLogger(Version.class.getName()); lgr.log(Level.SEVERE, ex.getMessage(), ex); } ``` 發生異常時,我們跳至`catch`塊。 我們通過記錄發生的情況來處理異常。 ```java } finally { if (rs != null) { try { rs.close(); } catch (SQLException ex) { Logger lgr = Logger.getLogger(MySqlVersionEx.class.getName()); lgr.log(Level.SEVERE, ex.getMessage(), ex); } } if (st != null) { try { st.close(); } catch (SQLException ex) { Logger lgr = Logger.getLogger(MySqlVersionEx.class.getName()); lgr.log(Level.SEVERE, ex.getMessage(), ex); } } if (con != null) { try { con.close(); } catch (SQLException ex) { Logger lgr = Logger.getLogger(MySqlVersionEx.class.getName()); lgr.log(Level.SEVERE, ex.getMessage(), ex); } } } ``` 無論是否接收到異常,都將執行`finally`塊。 我們正在嘗試關閉資源。 即使在此過程中,也可能會有異常。 因此,我們還有其他`try/catch`塊。 ### `IOException` 輸入/輸出操作失敗時,拋出`IOException`。 這可能是由于權限不足或文件名錯誤造成的。 `com/zetcode/IOExceptionEx.java` ```java package com.zetcode; import java.io.FileReader; import java.io.IOException; import java.nio.charset.StandardCharsets; public class IOExceptionEx { private static FileReader fr; public static void main(String[] args) { try { char[] buf = new char[1024]; fr = new FileReader("src/resources/data.txt", StandardCharsets.UTF_8); while (fr.read(buf) != -1) { System.out.println(buf); } } catch (IOException e) { e.printStackTrace(); } finally { if (fr != null) { try { fr.close(); } catch (IOException e) { e.printStackTrace(); } } } } } ``` 當我們從文件中讀取數據時,我們需要處理`IOException`。 當我們嘗試使用`read()`讀取數據并使用`close()`關閉讀取器時,可能會引發異常。 ### `ParseException` 解析操作失敗時,將引發`ParseException`。 `com/zetcode/ParseExceptionEx.java` ```java package com.zetcode; import java.text.NumberFormat; import java.text.ParseException; import java.util.Locale; public class ParseExceptionEx { public static void main(String[] args) { NumberFormat nf = NumberFormat.getInstance(new Locale("sk", "SK")); nf.setMaximumFractionDigits(3); try { Number num = nf.parse("150000,456"); System.out.println(num.doubleValue()); } catch (ParseException e) { e.printStackTrace(); } } } ``` 在示例中,我們將本地化的數字值解析為 Java `Number`。 我們使用`try/catch`語句處理`ParseException`。 ## Java 拋出異常 `Throwable`類是 Java 語言中所有錯誤和異常的超類。 Java 虛擬機僅拋出屬于此類(或其子類之一)的實例的對象,或者 Java `throw`語句可以拋出該對象。 同樣,在`catch`子句中,只有此類或其子類之一可以作為參數類型。 程序員可以使用`throw`關鍵字引發異常。 異常通常在引發異常的地方進行處理。 方法可以通過在方法定義的末尾使用`throws`關鍵字來擺脫處理異常的責任。 關鍵字后是該方法引發的所有異常的逗號分隔列表。 被拋出的異常在調用棧中傳播,并尋找最接近的匹配項。 `com/zetcode/ThrowingExceptions.java` ```java package com.zetcode; import java.util.InputMismatchException; import java.util.Scanner; import java.util.logging.Level; import java.util.logging.Logger; public class ThrowingExceptions { public static void main(String[] args) { System.out.println("Enter your age: "); try { Scanner sc = new Scanner(System.in); short age = sc.nextShort(); if (age <= 0 || age > 130) { throw new IllegalArgumentException("Incorrect age"); } System.out.format("Your age is: %d %n", age); } catch (IllegalArgumentException | InputMismatchException e) { Logger.getLogger(ThrowingExceptions.class.getName()).log(Level.SEVERE, e.getMessage(), e); } } } ``` 在示例中,我們要求用戶輸入他的年齡。 我們讀取該值,如果該值超出預期的人類年齡范圍,則會引發異常。 ```java if (age <= 0 || age > 130) { throw new IllegalArgumentException("Incorrect age"); } ``` 年齡不能為負值,也沒有年齡超過 130 歲的記錄。 如果該值超出此范圍,則拋出內置`IllegalArgumentException`。 拋出此異常表示方法已傳遞了非法或不適當的參數。 ```java } catch (IllegalArgumentException | InputMismatchException e) { Logger.getLogger(ThrowingExceptions.class.getName()).log(Level.SEVERE, e.getMessage(), e); } ``` 從 Java 7 開始,可以在一個`catch`子句中捕獲多個異常。 但是,這些異常不能是彼此的子類。 例如,`IOException`和`FileNotFoundException`不能在一個`catch`語句中使用。 下面的示例將說明如何將處理異常的責任傳遞給其他方法。 `thermopylae.txt` ```java The Battle of Thermopylae was fought between an alliance of Greek city-states, led by King Leonidas of Sparta, and the Persian Empire of Xerxes I over the course of three days, during the second Persian invasion of Greece. ``` 我們使用此文本文件。 `com/zetcode/ThrowingExceptions2.java` ```java package com.zetcode; import java.io.BufferedReader; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; public class ThrowingExceptions2 { public static void readFileContents(String fname) throws IOException { BufferedReader br = null; Path myPath = Paths.get(fname); try { br = Files.newBufferedReader(myPath, StandardCharsets.UTF_8); String line; while ((line = br.readLine()) != null) { System.out.println(line); } } finally { if (br != null) { br.close(); } } } public static void main(String[] args) throws IOException { String fileName = "src/main/resources/thermopylae.txt"; readFileContents(fileName); } } ``` 本示例讀取文本文件的內容。 `readFileContents()`和`main()`方法都不處理潛在的`IOException`; 我們讓 JVM 處理它。 ```java public static void readFileContents(String fname) throws IOException { ``` 當我們從文件讀取時,會拋出`IOException`。 `readFileContents()`方法引發異常。 處理這些異常的任務委托給調用者。 ```java public static void main(String[] args) throws IOException { String fileName = "src/main/resources/thermopylae.txt"; readFileContents(fileName); } ``` `main()`方法也會拋出`IOException`。 如果有這樣的異常,它將由 JVM 處理。 ## Java `try-with-resources`語句 `try-with-resources`語句是一種特殊的`try`語句。 它是 Java 7 中引入的。在括號中,我們放置了一個或多個資源。 這些資源將在語句末尾自動關閉。 我們不必手動關閉資源。 `com/zetcode/TryWithResources.java` ```java package com.zetcode; import java.io.BufferedReader; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.logging.Level; import java.util.logging.Logger; public class TryWithResources { public static void main(String[] args) { String fileName = "src/main/resources/thermopylae.txt"; Path myPath = Paths.get(fileName); try (BufferedReader br = Files.newBufferedReader(myPath, StandardCharsets.UTF_8)) { String line; while ((line = br.readLine()) != null) { System.out.println(line); } } catch (IOException ex) { Logger.getLogger(TryWithResources.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); } } } ``` 在示例中,我們讀取文件的內容并使用`try-with-resources`語句。 ```java try (BufferedReader br = Files.newBufferedReader(myPath, StandardCharsets.UTF_8)) { ... ``` 打開的文件是必須關閉的資源。 資源放置在`try`語句的方括號之間。 無論`try`語句是正常完成還是突然完成,輸入流都將關閉。 ## Java 自定義異常 自定義異常是用戶定義的異常類,它們擴展了`Exception`類或`RuntimeException`類。 使用`throw`關鍵字可以消除自定義異常。 `com/zetcode/JavaCustomException.java` ```java package com.zetcode; class BigValueException extends Exception { public BigValueException(String message) { super(message); } } public class JavaCustomException { public static void main(String[] args) { int x = 340004; final int LIMIT = 333; try { if (x > LIMIT) { throw new BigValueException("Exceeded the maximum value"); } } catch (BigValueException e) { System.out.println(e.getMessage()); } } } ``` 我們假定存在無法處理大量數字的情況。 ```java class BigValueException extends Exception { public BigValueException(String message) { super(message); } } ``` 我們有一個`BigValueException`類。 該類派生自內置的`Exception`類。 它使用`super`關鍵字將錯誤消息傳遞給父類。 ```java final int LIMIT = 333; ``` 大于此常數的數字在我們的程序中被視為`big`。 ```java if (x > LIMIT) { throw new BigValueException("Exceeded the maximum value"); } ``` 如果該值大于限制,則拋出自定義異常。 我們給異常消息`"Exceeded the maximum value"`。 ```java } catch (BigValueException e) { System.out.println(e.getMessage()); } ``` 我們捕獲到異常并將其消息打印到控制臺。 在 Java 教程的這一部分中,我們討論了 Java 中的異常。 {% endraw %}
                  <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>

                              哎呀哎呀视频在线观看