Java での Try-Catch-Finally | 例外処理

Feb 21 2023
· Try ブロック · Catch ブロック · 最後にブロック · すべてをまとめる · ネストされた Try ブロック · 複数の例外をキャッチする Try ブロック Try ブロックは、try/catch ブロックの最初の部分です。これらには、例外を引き起こす可能性のあるコードが含まれています。

· Try ブロック
· Catch ブロック
· Finally ブロック
·すべてをまとめる
·ネストされた Try ブロック
·複数の例外をキャッチする

ブロックを試す

Try ブロックは、try/catch ブロックの最初の部分です。これらには、例外を引き起こす可能性のあるコードが含まれています。Java では、ステートメントの結果が不明な場合、それらのステートメントをこの try ブロック内に置くことができます。try ブロックは、メソッドまたは別の try ブロックで使用できます。

tryブロックの後には常にcatchブロックが続き、関連する try ブロックで発生した例外を処理します。

IOExceptions の場合は、ファイルを作成、読み取り、書き込み、または閉じるコードを try ブロック内に置きます。

構文

例外ハンドラーを構築する最初のステップは、例外をスローする可能性のあるコードをtryブロック内で囲むことです。一般に、tryブロックは次のようになります。

try {
    code
}
catch and finally blocks . . .

例

ListOfNumbers クラスからwriteListメソッドの例外ハンドラーを構築するには、 writeListメソッドの例外スロー ステートメントをtryブロック内に囲みます。これを行う方法は複数あります。例外をスローする可能性のあるコードの各行を独自のtryブロック内に配置し、それぞれに個別の例外ハンドラーを提供できます。または、すべてのwriteListコードを 1 つのtryブロック内に配置し、それに複数のハンドラーを関連付けることもできます。次のリストでは、問題のコードが非常に短いため、メソッド全体に1 つのtryブロックを使用しています。

private List<Integer> list;
private static final int SIZE = 10;

public void writeList() {
    PrintWriter out = null;
    try {
        System.out.println("Entered try statement");
        FileWriter f = new FileWriter("OutFile.txt");
        out = new PrintWriter(f);
        for (int i = 0; i < SIZE; i++) {
            out.println("Value at: " + i + " = " + list.get(i));
        }
    }
    catch and finally blocks  . . .
}

ブロックサイドノートを試してみる

  • try ブロックには、例外をトリガーする可能性のあるコードのほかに、例外を引き起こさないコードも含めることができます (ただし、そうする必要はありません)。
  • プログラムには複数の try ブロックを含めることができます。さらに、1 つの try ブロックを別の try ブロックの中に入れることもできます。

キャッチブロック

try/catch ブロックの後半は catch ブロックです。try ブロックには例外を引き起こすコードが含まれていますが、catch ブロックには例外を処理するコードが含まれています。

Java では、catch ブロックは、try ブロックからキャッチされた例外を処理するために使用されます。catch ブロックにはコードが含まれており、try ブロック内で例外が発生した場合に実行されます。try ブロック内のステートメントの実行中にシステムで例外が発生した場合、システムは残りのステートメントをスキップし、対応する catch ブロックに制御を移します。

catch ブロックは、パラメーター内で例外の種類を宣言することで、try ブロックの例外をキャッチして処理します。catch ブロックで宣言された例外は、親クラス例外 (つまり、Exception) または生成された例外タイプである必要があります。ただし、最善の方法は、生成された例外のタイプを宣言することです。

catch ブロックは常に try ブロックの後に続きます。コントロールが Try ブロックから出てしまうと、それを Try ブロックに戻す方法はありません。

構文

tryブロックの直後に1 つ以上のcatchブロックを指定することで、例外ハンドラーをtryブロックに関連付けます。tryブロックの終わりと最初のcatchブロックの始まりの間にコードを置くことはできません。

try {
  
} catch (ExceptionType name) {

}

catchブロックには、例外ハンドラーが呼び出された場合に実行されるコードが含まれています。ランタイム システムは、例外ハンドラーがコール スタック内でExceptionType がスローされた例外の型と一致する最初のハンドラーである場合に、例外ハンドラーを呼び出します。スローされたオブジェクトを例外ハンドラーの引数に合法的に割り当てることができる場合、システムはそれが一致したとみなします。

Catch ブロックの引数

Catch ブロックは、キャッチ (処理) する例外のタイプを引数として 1 つ取ります。これらの引数は、非常に特殊なタイプの例外から、非常に一般的なすべての例外をキャッチするカテゴリまで多岐にわたります。

例

以下は、writeListメソッドの 2 つの例外ハンドラーです。

try {

} catch (IndexOutOfBoundsException e) {
    System.err.println("IndexOutOfBoundsException: " + e.getMessage());
} catch (IOException e) {
    System.err.println("Caught IOException: " + e.getMessage());
}

キャッチブロックの内容

catch ブロックの内容は、例外が発生したとき (たとえば、アクセスされているファイルが存在しないとき) に何が起こるかを示します。メッセージを出力することも、エラーを修正するために何らかの処理を行うコードを作成することもできます (たとえば、ファイル名をもう一度。

Catch ブロック メッセージ (例外の説明の表示)

catch ブロック内に任意のメッセージを出力できます。

toString() の使用

Throwable は、例外の説明を含む文字列を返すように、toString( ) メソッド (Object によって定義される) をオーバーライドします。この説明は、例外を引数として渡すだけで println( ) ステートメントに表示できます。たとえば、前のプログラムの catch ブロックは次のように書き換えることができます。

catch (ArithmeticException e) {
    System.out.println("Exception: " + e);
    a = 0; // set a to zero and continue
  }

Exception: java.lang.ArithmeticException: / by zero

  • getMessage() : 例外の種類ごとに固有のエラー メッセージを返します。これを println ステートメントと組み合わせます。
  • printStackTrace() : エラーの種類とプログラム内のどこでエラーが発生したかを出力します。これらのメソッドは、デバッグや例外の理由の検索に特に役立ちます。
  • すべての try ブロックには少なくとも 1 つの catch ブロックが必要です。
  • Try ブロックには複数の catch ブロックを含めることができます。右の例を参照してください。
  • Catch ブロックは、ペアになっている Try ブロックの直後に配置する必要があります。

最後にブロック

finally キーワードは、try ブロックに続くコード ブロックを作成するために使用されます。コードのfinallyブロックは、例外が発生したかどうかに関係なく常に実行されます。Finally ブロックを使用すると、保護されたコードで何が起こっても、実行したいクリーンアップ タイプのステートメントを実行できます。Finally ブロックは catch ブロックの最後に表示されます。finally ブロックは、オブジェクト参照を無効にし、I/O ストリームを閉じるために使用されます。

finallyブロックは、tryブロックが終了すると常に実行されます。これにより、予期しない例外が発生した場合でも、finallyブロックが確実に実行されます。しかし、finallyは単なる例外処理以上の用途に役立ちます。これにより、プログラマは、クリーンアップ コードがreturn、continue、またはBreakによって誤ってバイパスされることを回避できます。例外が予想されない場合でも、クリーンアップ コードをfinallyブロックに配置することは常に良い習慣です。

ランタイム システムは、 tryブロック内で何が起こったかに関係なく、常にfinallyブロック内のステートメントを実行します。したがって、クリーンアップを実行するのに最適な場所です。

構文

finally {
  // cleanup code
  }

writeListメソッドの次のfinallyブロックは、PrintWriterとFileWriterをクリーンアップして閉じます。

finally {
    if (out != null) { 
        System.out.println("Closing PrintWriter");
        out.close(); 
    } else { 
        System.out.println("PrintWriter not open");
    } 
    if (f != null) {
	    System.out.println("Closing FileWriter");
	    f.close();
	}	
}

  • 最後にブロックは、try/catch ブロックへのオプションの追加です。
  • 最後に、ブロックは、コードで例外が発生しても実行したいコードに使用されます。
  • これらは最後に実行されるものであり、プログラムを実行するたびに実行されます。
  • finally ブロックの使用法の 1 つは、プログラムの終了時にファイルが確実に閉じられるようにすることです。

private List<Integer> list;
private static final int SIZE = 10;

public void writeList() {
    PrintWriter out = null;
    try {
        System.out.println("Entered try statement");
        FileWriter f = new FileWriter("OutFile.txt");
        out = new PrintWriter(f);
        for (int i = 0; i < SIZE; i++) {
            out.println("Value at: " + i + " = " + list.get(i));
        }
    } 
    // catch blocks
    catch (IndexOutOfBoundsException e) {
        System.err.println("IndexOutOfBoundsException: " + e.getMessage());
    } 
    catch (IOException e) {
        System.err.println("Caught IOException: " + e.getMessage());
    }
    // finally block
  finally {
    if (out != null) { 
        System.out.println("Closing PrintWriter");
        out.close(); 
    } else { 
        System.out.println("PrintWriter not open");
    } 
    if (f != null) {
     System.out.println("Closing FileWriter");
     f.close();
 } 
}
}

ネストされた try ブロックが使用される場合、内側の try ブロックが最初に実行されます。内部の try ブロックでスローされた例外は、対応するcatch ブロックでキャッチされます。一致する catch ブロックが見つからない場合は、外側の try ブロックの catch ブロックが検査されます。このプロセスは、ネストされた try ステートメントがすべて使い果たされるまで継続されます。一致する catch ブロックが見つからない場合、プログラムは異常終了します。

ネストされた try-catch ブロックにアクセスします。

複数の例外をキャッチする

ご存知かもしれませんが、Java では複数の例外を処理するために複数の catch ブロックを使用できます。

例 :

catch (IOException ex) {
     logger.error(ex);
     throw new MyException(ex.getMessage());
catch (SQLException ex) {
     logger.error(ex);
     throw new MyException(ex.getMessage());
}

例 :

catch(IOException | SQLException ex){
     logger.error(ex);
     throw new MyException(ex.getMessage());
}

楽しく学習してください

Mouad Oumous Java WhatsApp グループに参加する

Mouad Oumous Telegram チャンネルに参加する

フォローして私たちの出版物をサポートしてください

Spring Boot の入門: 初心者向けの包括的なチュートリアル Spring Boot Security | Spring Boot SSO | Okta を使用した OAuth2 Java8 ストリーム ベースのインタビューでよく聞かれる質問 - パート 2 Java コーディングで ModelMapper を使用したオブジェクト マッピングのガイド: Javascript で配列をフラット化する Java8 ストリーム ベースでよく聞かれるインタビューの質問 - パート 1