LoginSignup
8
7

More than 5 years have passed since last update.

【Java 基本】 Checked Exception と Unchecked Exception について

Last updated at Posted at 2016-08-31

Checked: コンパイル時にチェックされる例外

もしあるメソッド内部のコードがchecked exceptionを投げうる場合は、そのメソッドはその例外をtry/catchで処理するか、throwsキーワードで指定しておく必要がある. (詳細: try/catch か throws Exception か)

例えば、以下のコードを考える. このコードでは、FileReader()を使っているが、FileReader()FileNotFoundExceptionというchecked exceptionを投げうる(throwsしている)ため、このままではコンパイルしない. また、readLine()メソッドや、close()メソッドも使っているが、それらもIOException を投げうる.

import java.io.*;

class Main {
    public static void main(String[] args) {
        FileReader file = new FileReader("C:\\test\\a.txt");
        BufferedReader fileInput = new BufferedReader(file);

        // Print first 3 lines of file "C:\test\a.txt"
        for (int counter = 0; counter < 3; counter++) 
            System.out.println(fileInput.readLine());

        fileInput.close();
    }
}

上記のコードをコンパイルしようとすると、以下のようなエラーになる.

Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - 
unreported exception java.io.FileNotFoundException; must be caught or declared to be 
thrown
    at Main.main(Main.java:5)

この問題を解決するためには、 throwsで例外のリストを指定するか、try/catchを使うことである. 今回の例では、 FileNotFoundExceptionIOExceptionのサブクラスなので、以下のようにIOExceptionのみを指定すれば良い.

import java.io.*;

class Main {
    public static void main(String[] args) throws IOException {
        FileReader file = new FileReader("C:\\test\\a.txt");
        BufferedReader fileInput = new BufferedReader(file);

        // Print first 3 lines of file "C:\test\a.txt"
        for (int counter = 0; counter < 3; counter++) 
            System.out.println(fileInput.readLine());

        fileInput.close();
    }
}

Unchecked: コンパイル時にチェックされない例外

C++では全ての例外がuncheckedなため、コンパイラに例外処理や例外指定を要求されることはなく、その対処は書き手に委ねられている.

Javaでは、throwableなクラスの中で、ErrorクラスとRuntimeExceptionクラス以下の例外のみunchecked exceptionで、他は全てcheckkedである.

以下のコードは、実行時にArithmeticExceptionを投げるが、コンパイルはできる. ArithmeticExceptionがunchecked exceptionであるからである.

class Main {
   public static void main(String args[]) {
      int x = 0;
      int y = 10;
      int z = y/x;
  }
}

なぜchecked/uncheckedの2つのタイプを持つのか?

起こりうる例外を指定するのはメソッドのインターフェースの責務

メソッド無いうで投げられうるchecked exceptionを全て指定するのは、メソッドのインターフェースの責務であり、そのメソッドを呼び出す元は、どのような例外が投げられうるのかを知ることで、対処できる. もし全ての例外がuncheckedであれば、APIの呼び出し元にとっては大変である.
引数、返り値とならんで、インターフェース定義の一部に、例外の指定もあると考えている.

APIクライアントが処理できない/するべきではない問題のみ、unchecked exceptionを用いる

例外を指定することが良いことならば、なぜunchecked exceptionは存在するのか?Runtime Exceptionも指定すれば?と思うかもしれない.
しかし、APIの呼び出し元が処理することができなかったり、処理することが望ましくない問題に対して、unchecked exceptionを投げる.
またRuntime exceptionはどこでも起きうるため、全てに対応を入れたら、コードの可読性を下げてしまう.

RuntimeExceptionを投げるタイミング

メソッドの呼び出し方が誤っている時にRuntime Exceptionを出すのが、一つの慣習である.

単に呼び出し元での例外処理が面倒だからという理由でRuntimeExceptionを使うことは、なるべく避けたい.

例外をcheckedにすべきか?uncheckedにすべきか?

APIクライアント(メソッドの呼び出し元)が例外を処理できる/すべきケースではcheckedを、そうでない場合はuncheckedを使用するべきである.


参考:
* Checked vs Unchecked Exceptions in Java
* Unchecked Exceptions — The Controversy

8
7
1

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
8
7