目次
結論
例外の3つの種類
検査例外(Checked Exception)
検査例外(Exception)
非検査例外(Unchecked Exception)
発生する検査例外を調べる方法
実行時例外(RuntimeException)
エラー(Error)
参考サイト、参考文献
結論
- javaでは、Throwableなクラスの中で、Errorクラスと、RuntimeExceptionクラス
を継承したクラスのみ非検査例外(Unchecked Exception)で、他は全て検査例外(Checked Exception) - Exceptionは、スレッドを跨がない
→裏を返すと、沢山のスレッドがある場合は、他のスレッドでExceptionが出ていても分からないので、Exceptionを考慮しないといけなくなる1
例外の3つの種類
- javaでは例外を大きく3つの種類に分けている
検査例外(Checked Exception)
検査例外(Exception)
- 検査例外(Exception)は、検査例外(チェック例外、Checked Exception)
- 検査例外を表すクラス:java.lang.Exception
- 主に、プログラム作成時に想定できる異常を通知するのに使用する
(その発生を十分に想定して、対処を考える筆よ言うがある例外的状況) - java.lang.Exceptionクラスを継承した例外の例)
- java.io.IOException:ファイルなどが読み書きできない
- java.net.ConnectException:ネットワークに接続できない
- java.sql.SQLException:データベース・アクセス・エラーまたはその他のエラー
- try-catch文か、throws節が必須(書かないとコンパイルエラーになる)
→プログラムで補足(catch)して処理するか、例外が発生するメソッドの宣言でthrows節を記述する(呼び元のメソッドにthrowする)ことが必須
補足(?):throws節について
- throws節をメソッドの宣言に記述することで、メソッド内で例外が発生した場合に自身のメソッド内で補足(catch)するのではなく、呼び出し元の関数に例外を投げる
アクセス修飾子 戻り値 メソッド名(引数) theows 例外クラス1, 例外クラス2{
// 例外処理を含む処理
}
public String readFile() throws IOException {
// ファイルの読み込み処理
}
- throws節をメソッドの宣言に記述することで、その処理で例外が発生することが分かる
- throws節で例外が記述されているメソッドは、呼び出し元の関数側で、その例外に対して何らかの処理をする事がjavaの仕様で決まっている
(例外を処理するコードを記述しないとコンパイルエラーになる)
発生する検査例外を調べる方法
実装の際に自分が使おうとしている命令で発生するExceptionを調べる方法💭
APIリファレンスを見よう!!
- APIリファレンスに「どのクラスのどのメソッドが、どのような例外を発生させる可能性があるのか」という情報が掲載されている
例)FileWriterクラスのコンストラクタ
↑メソッドやコンストラクタを呼び出した際にExcepoion系の例外がある場合、引数リストの後に「throws例外クラス」が表記されている
この例の場合は、「throws IOException」と記載があるため、「FileWriterクラスのコンストラクタを呼び出す(インスタンスを生成する)ときにはIOExceptionをキャッチするtry-catch文が必要になる」ということが分かる!!
非検査例外(Unchecked Exception)
実行時例外(RuntimeException)
- 実行時例外(RuntimeException)は、非検査例外(非チェック例外、Unchecked Exception)
- 実行時例外を表すクラス:java.lang.RuntimeException
- 主に、プログラム作成時に想定されないエラーを通知するために使用する
(必ずしも発生を想定すべきとまでは言えない例外的状況)
↑いちいち想定していると「キリがない」もの - java.lang.RuntimeExceptionクラスを継承した例外の例)
- java.lang.NullPointerException:変数がnullである
- java.lang.ArrayIndexOutOfBoundsException:配列の添え字が不正
- try-catch文も、throws節も書く必要が無い(書かなくてもコンパイルエラーにならない)
もし、try-catch文も、throws節も書かなかった場合
- catchブロックも、throws節も書かなかった場合、発生した実行時例外は、例外が発生したメソッドの呼び出し元のメソッドに、自動伝搬していく
- 実行時例外をどこでも捕捉しなかった場合、「例外が発生したメソッドが動いているスレッドが終了してしまう」
- 例外が発生したスレッドを開始させた別なスレッド、またはJavaVM自体には例外は伝播しない
- 例外を発生させたスレッドを開始させたのが
JavaVMの場合2
↑メインスレッドが終わるとアプリケーションが終了するため、もしこのスレッドがJavaVMのメインスレッドであった場合は、アプリケーション自体が終了する
関数のコールと、スレッドは別な話です
(↑自分はごっちゃに考えてしまっていた。。。)
エラー(Error)
エラー(Error)は、非検査例外(非チェック例外、Unchecked Exception)
- エラーを表すクラス:java.lang.Error
- 「通常のアプリケーションでは 捕捉すべきではない 重大な問題」を示すクラス
(例外とは異なり、システムの動作を継続できない「致命的なエラー」を示す)
↑回復の見込みが無い、致命的な状況 - java.lang.Errorクラスを継承した例外の例)
- java.lang.OutOfMemoryError:メモリ不足
- java.lang.ClassFormatError:クラスファイルが壊れている
- try-catch文も、throws節も書く必要が無い(書かなくてもコンパイルエラーにならない)
「Errorを捕捉すべきではない」理由
- Errorが発生する状況は大抵の場合、アプリケーションが異常状態に陥っており、速やかにプログラムを終了させるべきだから
→アプリケーションが沈黙する(固まったまま何も動作しなくなる)のは最悪の事態といえるため、速やかに終了すべき
参考サイト、参考文献
-
谷本心,阪本雄一郎,岡田拓也,秋葉誠,村田賢一郎. Java本格入門 ~モダンスタイルによる基礎からオブジェクト指向・実用ライブラリまで. 技術評論社, 2017, p.178-181.
-
中山清喬, 国本大悟. スッキリわかるJava入門 第3版 (スッキリわかる入門シリーズ). 株式会社インプレス, 2019, p.658-662.
-
Threadクラスのstart()メソッドは、あくまでスレッドを開始させるだけで、開始した後は正常終了したのか、Exceptionが出て異常終了したのか、そもそも開始したスレッドの処理が終わったのかは検知しない ↩
-
Java仮想マシン = Javaのプログラムを動かすためのソフトウエア ↩