【Java】例外処理で例外をキャッチする

Java では、例外をスローする可能性のあるステートメントはすべてtry ... catchキャッチできます。例外を引き起こす可能性のあるステートメントをtry { ... }中央に配置し、catch を使用して対応するクラスExceptionとそのサブクラスをキャプチャします。

複数の catch ステートメント

複数のcatchステートメントを使用して、それぞれがcatch対応するExceptionクラスとそのサブクラスをキャプチャすることができます。JVM例外がキャッチされた後、catchステートメントは上から下に照合され、特定の照合の後、コード ブロックcatchが実行され、その後照合は続行されません。catch

簡単に言えば、catch複数のステートメントのうち 1 つだけを実行できます。例えば:

public static void main(String[] args) {
    
    
    try {
    
    
        process1();
        process2();
        process3();
    } catch (IOException e) {
    
    
        System.out.println(e);
    } catch (NumberFormatException e) {
    
    
        System.out.println(e);
    }
}

複数ある場合catchcatch順序は非常に重要です。サブクラスを最初に記述する必要があります。例えば:

public static void main(String[] args) {
    
    
    try {
    
    
        process1();
        process2();
        process3();
    } catch (IOException e) {
    
    
        System.out.println("IO error");
    } catch (UnsupportedEncodingException e) {
    
     // 永远捕获不到
        System.out.println("Bad encoding");
    }
}

上記のコードの場合、UnsupportedEncodingException例外は のIOExceptionサブクラスであるため、例外はキャッチされません。例外がスローされるとUnsupportedEncodingException、それがcatch (IOException e) { ... }捕捉されて実行されます。

したがって、正しい書き方はサブクラスを前に置くことです。

public static void main(String[] args) {
    
    
    try {
    
    
        process1();
        process2();
        process3();
    } catch (UnsupportedEncodingException e) {
    
    
        System.out.println("Bad encoding");
    } catch (IOException e) {
    
    
        System.out.println("IO error");
    }
}

finallyステートメント
例外が発生するかどうかに関係なく、クリーンアップなどのステートメントを実行したい場合、どのように記述すればよいでしょうか?

実行ステートメントは複数回記述することができます。通常どおり実行されるステートメントを配置しtrycatchそれぞれを再度記述します。例えば:

public static void main(String[] args) {
    
    
    try {
    
    
        process1();
        process2();
        process3();
        System.out.println("END");
    } catch (UnsupportedEncodingException e) {
    
    
        System.out.println("Bad encoding");
        System.out.println("END");
    } catch (IOException e) {
    
    
        System.out.println("IO error");
        System.out.println("END");
    }
}

上記のコードは、例外が発生したかどうかに関係なく、System.out.println("END");このステートメントを実行します。

では、これらの重複コードを削除するにはどうすればよいでしょうか? Java的try ... catchこのメカニズムは、エラーの有無にかかわらず実行されることが保証されたfinallyステートメント、finallyつまりステートメントのブロックも提供します。上記のコードは次のように書き換えることができます。

public static void main(String[] args) {
    
    
    try {
    
    
        process1();
        process2();
        process3();
    } catch (UnsupportedEncodingException e) {
    
    
        System.out.println("Bad encoding");
    } catch (IOException e) {
    
    
        System.out.println("IO error");
    } finally {
    
    
        System.out.println("END");
    }
}

finallyいくつかの機能があることに注意してください。

finallyステートメントは必須ではなく、記述してもしなくても構いません。
finallyステートメントは常に最後に実行されます。
例外が発生しない場合、ステートメント ブロックは通常どおり実行されtry { ... }、その後実行されますfinally例外が発生した場合は、try { ... }ステートメント ブロックの実行を中断し、一致する catch ステートメント ブロックの実行にジャンプし、最後にそれを実行しますfinally

finally一部のコードを確実に実行するために使用されていることがわかります。

場合によっては、何も存在せずcatchtry ... finally構造体のみを使用することもできます。例えば:

void process(String file) throws IOException {
    
    
    try {
    
    
        ...
    } finally {
    
    
        System.out.println("END");
    }
}

このメソッドではスローされる可能性のある例外を宣言しているため、 を記述する必要はありませんcatch

複数の例外のキャッチ
一部の例外の処理ロジックは同じでも、例外自体に継承関係がない場合は、複数の catch 句を記述する必要があります。

public static void main(String[] args) {
    
    
    try {
    
    
        process1();
        process2();
        process3();
    } catch (IOException e) {
    
    
        System.out.println("Bad input");
    } catch (NumberFormatException e) {
    
    
        System.out.println("Bad input");
    } catch (Exception e) {
    
    
        System.out.println("Unknown error");
    }
}

IOException合計を処理するコードはNumberFormatException同じであるため、2 つの使用方法を組み合わせることができます。

public static void main(String[] args) {
    
    
    try {
    
    
        process1();
        process2();
        process3();
    } catch (IOException | NumberFormatException e) {
    
     // IOException或NumberFormatException
        System.out.println("Bad input");
    } catch (Exception e) {
    
    
        System.out.println("Unknown error");
    }
}

まとめ

使用する場合try ... catch ... finally:

複数のcatchステートメントの一致順序は非常に重要であり、サブクラスを最初に配置する必要があります。

finallyこのステートメントは、例外の有無にかかわらず実行されることを保証します。これはオプションです。

ステートメントcatchは複数の非継承例外と一致することもあります。

おすすめ

転載: blog.csdn.net/ihero/article/details/132160389
おすすめ