Java 异常的示例

整理Java异常的信息。

种类中的例外(继承关系)

image.png

クラス 概要 例 Throwable 例外の基底クラスthrows/try-cathc必要 – Error 致命的エラーthrows/try-cathc不要 StackOverflowErrorOutOfMemoryError Exception 検査例外throws/try-cathc必要(ないとコンパイルエラー) IOExceptionSQLException RuntimeException 非検査例外throws/try-cathc不要検査例外をラップしたExceptionを作ることがある NullPointerExceptionNumberFormatException

异常检查例外

必须强制调用方进行某种异常处理的异常。
如果不使用throws或try-catch将导致编译错误。
为了不丧失异常信息而不处理异常,可以通过throws将异常抛给调用方。

    メソッド宣言 throws で呼び出し元に例外を投げる
public void method() throws IOException {
    List<String> lines = Files.readAllLines(Paths.get("xxx"));
    ...
}
    処理内で try-catch して例外処理
try {
    List<String> lines = Files.readAllLines(Paths.get("xxx"));
    ...
} catch (IOException e) {
    // 例外処理
    ...
}

RuntimeException是一个非受检异常。

不需要強制呼叫方處理例外的例外
即使不進行例外處理,也不會發生編譯錯誤(而會產生執行時錯誤)
有時會將檢查例外包裝成非檢查例外
這樣就可以在不改變呼叫方方法定義的情況下處理,而不會產生編譯錯誤

    検査例外を非検査例外でラップ
try {
    List<String> lines = Files.readAllLines(Paths.get("xxx"));
    ...
} catch (IOException e) { 
    throw new RuntimeException(e);
}

异常处理的语法

整理Java的异常处理语法。
有两种语法:方法声明throws和try-catch块处理。
如果发生Exception检查异常,如果没有声明编译错误。
对于RuntimeException非检查异常,不需要声明,但可以通过在JavaDoc中添加注释来向其他开发者说明异常情况。

方法声明抛出异常

当在调用元的类中执行异常处理时,需要按照以下方式进行描述:
针对发生的异常进行throws的记录。

public void method() throws IOException, ParseException { // 「,」区切りで複数記載OK 
    List<String> lines = Files.readAllLines(Paths.get("xxx"));
    Object text = new DateFormatter().stringToValue("test");
    ...
}

在代码中使用try-catch-finally来处理异常。

在处理过程中进行异常处理的说明方法
对于发生的异常逐个在catch中进行说明
在catch后面的异常处理中也可以进行throw操作
在这种情况下,要与方法声明的throws一起进行说明
如果有必要在异常发生之后始终执行处理,可以在finally中进行说明。

try {
    List<String> lines = Files.readAllLines(Paths.get("xxx"));
    Object text = new DateFormatter().stringToValue("test");
    Thread.sleep(1);
    ...
} catch (IOException | ParseException e) { // 「|」で複数記載OK
    // 例外処理
    ...
} catch (InterruptedException e) { // 「catch」は複数記載OK
    // 例外処理
    ...
    // throw することも可能(その場合、メソッド宣言 throws も必要)
    throw e;
} finally {
    // 例外発生に関係なく必ず実行する処理
    ...
}

– 使用 try-with-resources 关闭资源

在访问文件、数据库等外部资源时需要执行关闭操作以断开连接。
如果不关闭连接,可能会导致连接保持打开状态,从而导致意外的错误。
在Java中,可以通过使用try-with-resources(仅适用于实现了AutoCloseable接口的类)来解决这个问题。

// try() の中で変数宣言したものが close 対象、「;」で複数行記載OK
try (BufferedReader br = Files.newBufferedReader(Paths.get("xxx"))) {
    ...
} catch (IOException e) {
    ...
}

– 特例包装

当把异常转换为另一个异常并抛出时,应该包装原始异常,以免丢失异常信息。
如果不包装异常而是生成另一个异常,原始异常信息将会丢失,导致无法确定错误的原因。
有两种情况可以将异常包装为另一个异常。

    アプリ(機能)独自の例外にして例外処理を統一する
    検査例外を非検査例外にして呼び出し元に影響(コンパイルエラー)が出ないようにする
try {
    List<String> lines = Files.readAllLines(Paths.get("xxx"));
    ...
} catch (IOException e) { 
    // e(例外) を別の例外を生成するときに引数として渡す
    throw new RuntimeException(e);
    // throw new RuntimeException("error message", e);
}

在例外处理中有问题

在异常处理中,如果隐藏或改变异常,那么就无法确定其原因。另外,如果对广泛的异常(例如,Exception等)进行throws和catch处理,那么即使是意外的异常也会被处理,从而导致无法察觉到错误。请列出应避免在异常处理中做的事情。

将例外隐藏起来 (wō tuì)

只有选择一个合适的中文选项:
在捕获异常后不进行处理就结束,这将被视为隐瞒
对于不处理异常的类,应该在不捕获的情况下向调用者抛出异常(只需在方法声明中使用throws)
即使在处理异常时,也应该在捕获并处理后向调用者抛出异常(使用throws和在捕获处理中使用throw)
如果有意不抛出异常时,最好记录异常信息,如日志输出,以便备查
如果不保留任何信息,可能会导致未预料的异常被忽略,引发其他问题的可能性。

    隠蔽(握り潰す)
try {
    List<String> lines = Files.readAllLines(Paths.get("xxx"));
    ...
} catch (IOException e) {
    // 処理しないで握り潰す
    // 意図的にやるときでも log 出力してほしい、明らかに不要なときでもコメントに意図を記載
}
    呼び出し元に throw(メソッド宣言 throws のみ)
public void method() throws IOException {
    List<String> lines = Files.readAllLines(Paths.get("xxx"));
    ...
}
    呼び出し元に throw (catch して処理して throw)
public void method() throws IOException {
    try {
        List<String> lines = Files.readAllLines(Paths.get("xxx"));
        ...
    } catch (IOException e) {
        ...
        throw e; 
        // 別の Exception にラップ(設定)するでもOK 
        // throw new XxxException(e);
        // throw new XxxException("messeage", e);
    }
}

消除例外

捕捉到异常后不生成并抛出不包装的“异常”,将会丢失异常信息。
当在异常处理中新建异常时,基本原则是包装并设置已捕获的异常,以避免丢失异常信息。
如果故意不进行包装时,最好记录异常信息,例如通过日志输出。
如果不留下任何信息,可能会导致意外的异常被放置而引发其他问题。

    消失
try {
    List<String> lines = Files.readAllLines(Paths.get("xxx"));
    ...
} catch (IOException e) {
    // e をラップ(設定)しない Exception 生成で元の例外を消失
    // 意図的にやるときでも log 出力してほしい、明らかに不要なときでもコメントに意図を記載
    throw new XxxException("message");
}
    例外をラップ(設定)
try {
    List<String> lines = Files.readAllLines(Paths.get("xxx"));
    ...
} catch (IOException e) {
    // e をラップ(設定)すればOK
    throw new XxxException("message", e);
}

广泛的异常指定

使用throw和catch等广泛的异常类时,即使对于意外的异常也会进行处理。因此,当发生非预期的异常时,可能无法正确处理异常。特别是在进行故意的隐藏等操作的部分,可能会丢失异常信息。

    余計な例外処理
// Exception ではなく IOException など発生する例外のみにする
public void method() throws Exception {
    try {
        List<String> lines = Files.readAllLines(Paths.get("xxx"));
        ...
    } catch (Exception e) {
    // Exception ではなく IOException など発生する例外のみにする
        ...
        throw e; 
    }
}

只输出堆栈跟踪的例外处理

在捕获的异常处理中,只有e.printStackTrace(),这会导致应用程序停止和根据设置丢失异常信息。结果就会变得和隐藏(抑制)一样。在教科书等示例中可能很常见,但实际应用程序中更常用的是日志输出而不是堆栈跟踪输出。

try {
    List<String> lines = Files.readAllLines(Paths.get("xxx"));
    ...
} catch (IOException e) {
    // これのみだと隠蔽と同じことになる
    // throw して呼び出し元で処理するか log 出力して例外情報を残してほしい
    e.printStackTrace;
}

bannerAds