2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

例外処理の実装方法(Java)

Posted at

今まで例外処理として、try-catch、throws等について、理解されていないままプロジェクトに参画されている方を結構見てきました。
これからプロジェクトへ参画される方や、実は自分もよくわからないまま実装しちゃってる・・・って方向けに例外処理の実装方法を簡単に説明します。

目次

1.例外クラス
2.検査例外(checked例外)
3.非検査例外(unchecked例外)
4.例外処理
5.まとめ

1. 例外クラス

プログラム実行中に例外が発生すると、本来想定しているプログラムがそこで一旦終了され、実装した例外処理が実行されます。

Javaの、例外クラス(Throwable)は、大きく分けて、以下二つの例外に分類されます。

  • 検査例外(checked例外)
  • 非検査例外(unchecked例外)

それぞれの例外については後述で説明しますが、対象となるクラスは以下となります。

検査例外

非検査例外

図で表すと以下のイメージです。

image.png

2. 検査例外(checked例外)

コンパイラが例外処理を実装しているか検査する例外。
例外処理の実装が必須。(例外処理を実装しないとコンパイルエラーになる)

検査例外(checked例外)の対象クラスの例

3. 非検査例外(unchecked例外)

コンパイラが例外処理を実装しているか検査しない例外。
例外処理の実装が任意。(例外処理を実装していなくてもコンパイルエラーにならない)

非検査例外(unchecked例外)の対象クラスの例

Errorのサブクラス例

RuntimeExceptionのサブクラス例

4. 例外処理

検査例外をthrowするメソッドを利用する場合、例外処理を実装しないと、コンパイルエラーになってしまいます。
尚、例外のthrowとは、例外が投げられる(throw:スロー)ことを指します。
javaのthrowは、その処理の呼び出し元に対して例外を投げます。

以降、FileReaderクラスを例に説明していきます。

throwされる可能性がある例外クラス

FileReaderのコンストラクタを利用すると、FileNotFoundExceptionthrowされる可能性があります。
throws句の後続に記載されている、FileNotFoundExceptionが、throwされる可能性がある例外クラスです。

public FileReader(String fileName)
           throws FileNotFoundException

このように、throws句で定義された例外クラスを、利用する側で例外処理をしてあげる必要があります。

例外処理の実装方法

例外処理を行うには、以下の2択となります。

  • try-catch句で処理する
  • try-catch句を使わずにthrowsに定義する

try-catch句で処理する

public void hoge() {
    try {
        FileReader fileReader = new FileReader("/hoge.txt");
        System.out.println("Success");
    } catch (FileNotFoundException ex) {
        ex.printStackTrace();
        System.out.println("Failed");
    }
    System.out.println("Finish!!");
}

以下の箇所で、FileNotFoundExceptionがthrowされる可能性があるので、try-catchで囲ってあげます。

FileReader fileReader = new FileReader("/hoge.txt");

try句

例外が発生する可能性がある箇所を、tryブロックで囲います。

try {
	FileReader fileReader = new FileReader("/hoge.txt");
	System.out.println("Success");
}

System.out.println("Success")で、FileNotFoundExceptionは発生しませんが、new FileReader("/hoge.txt")で、FileNotFoundExceptionが発生しなかった場合のみ、実行させるために一緒にtryブロックにいれてあげます。

catch句

tryブロックの中で、発生した例外をcatch(キャッチ)した際の処理を記述します。

catch (FileNotFoundException ex) {
	ex.printStackTrace();
	System.out.println("Failed");
}

tryブロックの中で、FileNotFoundExceptionが発生したら、ここへすぐさま飛んできて、ブロック内の処理を実行します。
実際の運用では、ログの出力や、DBのcommitやrollbackをさせたりします。

この例ではhogeメソッドの呼び出し元からは、以下が実行され、例外が発生した事実はわかりません。

  • コンソールにStackTrace(例外の情報)を出力
  • コンソールに、Failedを出力

なお、例外が発生しなかった場合、catchブロック内の処理は実行されません。

流れを表すとこんな感じ。
image.png

もし、呼び出し元に、例外が発生したことを通知するために、対象の例外を同様にthrowする場合は以下のようになります。

public void hoge() throws FileNotFoundException { // throws句を追加
    try {
        FileReader fileReader = new FileReader("/hoge.txt");
        System.out.println("Success");
    } catch (FileNotFoundException ex) {
        ex.printStackTrace();
        System.out.println("Failed");
        throw ex; // catchした例外をthrow
    }
    System.out.println("Finish!!");
}

catchした、例外を呼び出し元へ例外を通知する場合は、以下のようにcatchした例外をthrowします。

throw ex;

そうすると、このメソッドはFileNotFoundExceptionをthrowする可能性のあるメソッドとなるため、メソッド定義としてthrows句を追加します。

public void hoge() throws FileNotFoundException {

こうすることで、hogeメソッドは、FileNotFoundExceptionをthrowするメソッドとなります。

流れを表すとこんな感じ。
image.png

finally句で、正常時・異常時でも必ず処理させたい

上記の例では、例外が発生して、例外をthrowすると、後続の処理が続行されずに、
System.out.println("Finish!!");が実行されません。

例外が発生しても、していなくても、実行させたい処理がある場合は、finallyブロック内に処理を記載してあげます。

finally {
	System.out.println("Finish!!");
}

こうすることで、例外が発生しても、していなくても最終的に、必ずSystem.out.println("Finish!!")が実行されます。

流れを表すとこんな感じ。

例外が発生した場合

image.png

例外が発生しなかった場合(正常系)

image.png

try-catch句を使わずにthrowsに定義する

public void hoge() throws FileNotFoundException {
    FileReader fileReader = new FileReader("/hoge.txt");
    System.out.println("Success");
    System.out.println("Finish!!");
}

この書き方は、try-catch句を使わずに、throws FileNotFoundExceptionのみを定義します。
こうすることで、new FileReader("/hoge.txt")で、FileNotFoundExceptionが発生した際に、すぐさまメソッドを終了し、呼び出し元へFileNotFoundExceptionをthrowします。
Successのコンソール出力は実行されません。

全く使わないということはないですが、例外が発生した際に、適切なログ出力を施すことを考えると現実的にはtry-catch句で例外処理を行った上で、throwしてあげたりするのが現実出来かと思います。

流れを表すとこんな感じ。
image.png

5. まとめ

  • 検査例外(RuntimeExceptionを除くExceptionのサブクラス)がthrowされるメソッドは、例外処理を施す
  • 例外処理はtry-catch句で処理するか、throws句に定義させる
  • try-catchでcatchさせたとしても、throwさせる場合は、throws句も定義する
2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?