例外処理のメカニズムであるtry-catch-finallyは、Javaの言語発展の初期から追加されました。主な目的は、エラー処理を構造化して管理し、作業コードとエラー処理コードを分けることです。
問題:標準外またはエラーな動作は例外(exception)を発生させます。try-catchを使わない場合、それを単に呼び出しスタックの上に伝達することしかできません。このアプローチでは、プログラムが異常終了する可能性があります。
解決策は、try { } catch { } finally { }を使用することで、期待される例外を処理し、リソースの解放、ファイルの閉鎖、トランザクションのロールバックなどの終了処理を確実に実行することです。
コードの例:
try { FileInputStream fin = new FileInputStream("test.txt"); int data = fin.read(); } catch (IOException e) { System.out.println("ファイル操作中のエラー: " + e.getMessage()); } finally { fin.close(); }
主な特徴:
tryブロックは潜在的なエラーコードを含むcatchは例外をキャッチして処理するfinallyは常に実行され、return/exceptionの場合でもfinallyが実行されないことはありますか?
はい、ブロック内にSystem.exit()がある場合、プロセスが異常終了した場合、またはJVMが物理的にクラッシュした場合などです。
finallyなしでtry-catchを使用できますか?
はい、finallyブロックは必須ではありません。ただし、リソースのクリーンアップが必要な場合は、通常使用されます。Java 7以降はtry-with-resourcesがあります。
finallyで例外が発生したらどうなりますか?
finally内で新しいエラーが発生した場合、それは元のエラーを「上書き」します(個別にキャッチされていない限り)、これは問題を隠す可能性があります。
try { throw new RuntimeException("tryで失敗"); } finally { throw new RuntimeException("finallyで失敗"); } // 結果のスタックトレースは「finallyで失敗」のみ
catch(Exception e) {} が空)throw e; がnew Exception(e)なし)プロジェクトでは、finallyブロックに自身がIOExceptionをスローする可能性のあるコードが含まれていました。try中のエラーで元の例外が完全に失われ、エラー診断が非常に困難になりました。
利点:
欠点:
finallyの代わりに、チームはtry-with-resourcesに移行しました。各リソースはAutoCloseableを実装し、解放が自動的に行われ、例外は独自のエラーとしてログに記録されます。
利点:
欠点: