ThrowableってExceptionより上位なの?
恥ずかしながらこの疑問を持ったため調べてみました。
というのも、実装中に下記見エラーをキャッチしている箇所で、ExceptionではなくThrowableでキャッチしている箇所があり、SonoraQubeから指摘を受けた。ためです。
Javaの例外クラスは、以下のような階層構造
java.lang.Object
└ java.lang.Throwable
├ java.lang.Error
└ java.lang.Exception
└ java.lang.RuntimeException
この図が示すように、Throwable がすべての例外とエラーのスーパークラスであり、その直下に Error と Exception が存在します。
1,java.lang.Throwable
定義: Javaの例外クラス階層の最上位に位置するクラスです。
-
役割: * Error と Exception の両方の基底クラスです。
例外発生時のスタックトレースなどの情報を保持します。 -
特徴: * throw 文でスローできるのは、Throwable クラスか、そのサブクラスのインスタンスだけです。
開発者がcatch (Throwable)と広範に捕捉することは推奨されません。これは、Errorも捕捉してしまうため、システムレベルの深刻な問題まで隠蔽してしまう可能性があるからです。
2,java.lang.Error
定義: Throwable を継承するクラスです。
-
役割: 回復が不可能な、システムレベルの深刻な問題を示します。
-
特徴:プログラム自体のバグではなく、JVMやシステムリソースの限界など、外部要因によって発生することが多いです。
アプリケーションが Error を捕捉して回復することは、通常は不可能です。
したがって、catch ブロックでErrorを捕捉することは推奨されません。 -
代表的な例:
java.lang.OutOfMemoryError: JVMが新しいオブジェクトを生成するのに十分なメモリを確保できない場合に発生します。
java.lang.StackOverflowError: メソッド呼び出しが無限ループに陥るなどして、スタックのメモリが使い果たされた場合に発生します。
java.lang.NoClassDefFoundError: 実行時にクラスの定義が見つからない場合に発生します。
3,java.lang.Exception
定義: Throwable を継承するクラスです。
-
役割: 回復可能な、アプリケーションレベルの例外を示します。
-
特徴:
try-catch ブロックで捕捉し、適切な処理を記述することで、プログラムの実行を継続できることが期待されます。
ほとんどのExceptionは、コンパイル時にチェックされる検査例外ですが、RuntimeExceptionとそのサブクラスは非検査例外として扱われます。 -
代表的な例:
-
検査例外:
java.io.IOException: ファイルの読み書きエラー。
java.sql.SQLException: データベースアクセスエラー。 -
非検査例外(RuntimeException):
java.lang.NullPointerException: ヌルポインタ参照。
java.lang.IllegalArgumentException: 不正な引数。
まとめ
このように、ErrorとExceptionは、同じThrowableという親を持っていますが、その意味と役割は全く異なります。プログラムのバグによって引き起こされる可能性のある回復可能な問題をExceptionとして扱い、回復のしようがないシステムレベルの問題をErrorとして扱うことで、Javaの例外処理は整理されています。め