検査例外と非検査例外はの違いはなんとなくわかるものの、詳しく理解できていなかったので、調べてみました。
検査例外と非検査例外
Exceptionクラスには検査例外と非検査例外(例外処理を記述したかコンパイラが検査しない)が混在しています。
検査例外は正しいプログラムを書いても発生し得る例外です。そのため、例外が発生した場合の処理をあらかじめ書いていないとコンパイルエラーとなってしまいます。
※ファイルが壊れていて開けなかったなど、プログラムでは回避のしようがないため、あらかじめ例外処理を行う必要がある。
よくみる検査例外
検査例外にはどんなものがあるのでしょうか。軽くみてみます。
- IllegalAccessException:アプリケーションが、配列以外のインスタンス作成、フィールドの設定または取得、メソッドの呼び出しを試みた場合に、IllegalAccessException がスローされます。
- IOException: 入出力処理の失敗、または割り込みの発生によって生成される例外の汎用クラスです。
- SQLException: データベースアクセスエラーまたはその他のエラーに関する情報を提供する例外です。
- InterruptException: あるスレッドが待ち状態、休止状態、または占有されているとき、アクティビティーの前かその間のいずれかにそのスレッドで割り込みが発生した場合にスローされます。
非検査例外 参考ページ
非検査例外であるRuntimeExceptionについては以下でまとめています。
違いのわかるサンプルコード
大きく検査例外と非検査例外での動きの違いをまとめています。
検査例外の場合
検査例外は例外の発生の有無にかかわらず必ずどこかで例外をcatchし処理する必要があります。
コンパイルエラーになる
以下のサンプルコードは検査例外が発生しているのにthrows宣言もtry-catchも書かれていない状況です。そのためコンパイルエラーとなっています。
import java.io.IOException;
public class Main {
public static void main(String[] args) {
Test tst = new Test();
tst.throwsTest();
}
}
class Test{
public void throwsTest(){
throw new IOException(); // 検査例外をthrow
}
}
※ throwを使って意図的に例外を発生させています。例外を自作する時に使われたりします。
非検査例外の場合
非検査例外の場合、コンパイラ側が例外処理の有無の確認はしません。
コンパイルエラーにならない
非検査例外はコンパイラ側で処理の有無の確認は行いません。
import java.lang.Exception;
public class Main {
public static void main(String[] args){
Test tst = new Test();
tst.throwsTest();
}
}
class Test{
public void throwsTest(){
throw new RuntimeException(); // 非検査例外をthrow
}
}
上記の場合、意図的にRuntimeExceptionを発生させているため実行時エラーとなります。
おわり
例外はわかりそうで、よくわからないことが多いです。
今回取り上げた違いだけが全てではないような気もしますが、Java SE Silverのテスト勉強をしているとこの違いがなかなか響いてきたのでまとめてみました。