Javaでは、例外はチェック例外(checked)と非チェック例外(unchecked)に分けられます。
Exceptionから派生していますが、RuntimeExceptionからは派生していません。コンパイラーは、これらを明示的にtry-catchで扱うか、throwsで宣言することを要求します。RuntimeExceptionから派生しています。コンパイラーはそれらを必ずしも処理する必要はありません。public void readFile(String file) throws IOException { /* ... */ } // チェック例外 public void divide(int a, int b) { int res = a/b; } // 非チェック例外 (ArithmeticException)
主なポイントは、チェック例外は期待される回復可能な状況(例えば、入出力エラー)のために使用されるのに対し、非チェック例外はプログラムのロジックのエラーや回復できないクリティカルな状況(例えば、NullPointerException)のために使用されるということです。
質問: メソッドが非チェック例外をスローする可能性があるとき、それを処理する必要がありますか?またはthrowsで宣言する必要がありますか?
回答: いいえ。回復不能(非チェック)例外をチェックまたは宣言する必要はありません。処理はあなたの裁量に任されています;try-catchを使用することもできますが、一般的にはグローバルハンドラーまで「落ちる」ことを許可します。
public void foo() { throw new IllegalArgumentException(); } // 処理や宣言を必要としません
例
銀行APIプロジェクトで、入出力エラーを処理する際にチェック例外の代わりに
RuntimeExceptionをスローした結果、クライアントはそれらを処理する必要がなくなり、サーバー接続の喪失時に不正な動作を引き起こし、アプリケーションがユーザーに通知せずに「落ちる」ことになりました。
例
開発者がメソッドのシグネチャに不必要に多くの
throws Exceptionを宣言したため、上記の使用されるすべてのメソッドがtry-catchまたは別のthrowsを使用する必要がありました。これによりコードが散らかり、可読性が低下し、リファクタリングが困難になりました。
例
あるマイクロサービスでは、すべての例外を一般的な
catch (Exception e)で捕捉していました。これにより、非チェック例外(例えば、NullPointerException)も捕捉され、重要なエラーが「静かに」無視される結果となり、サービスが不正なデータで動作することになりました。