java-beginner.com ブログ

プログラミングを学習するブログ(Javaをメインに)

try-catch文

投稿日:

最終更新日:2016年08月28日

アイキャッチ

こんにちは。「Javaを復習する初心者」です。

今回はtry-catch文について復習しました。

try-catch文についての復習なのですが、まずはtry-catch文を使わない状態のプログラムを書き、そのあとで発生する例外についてtry-catch文で制御するということをやりました。

例外を発生させる

次のプログラムは入力値をString型で受け取り、コンソールに表示する動作をするだけのプログラムです。

入力値を表示するプログラム

        Scanner scanner = new Scanner(System.in);
        String s = scanner.next();
        scanner.close();

        System.out.println("入力値:" + s);

public String next()メソッドで入力値をString型変数sに格納しています。では、入力値を次のようにint型に変換する場合を考えます。nextInt()メソッドがありますが、try-catch文の練習のため使わないことにします。

int型に変換

        Scanner scanner = new Scanner(System.in);
        String s = scanner.next();
        scanner.close();

        int n = Integer.parseInt(s); // String型をint型に変換

        System.out.println("入力値:" + s);

入力値が数字でない場合、以下のような例外が発生し、コンソールに内容が出力されます。以下は入力値が「a」の場合です。

「a」を入力した場合

Exception in thread "main" java.lang.NumberFormatException: For input string: "a"
	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.lang.Integer.parseInt(Integer.java:580)
	at java.lang.Integer.parseInt(Integer.java:615)
	at test.HelloTryCatch.main(HelloTryCatch.java:13)

例外をキャッチ

この例外はIntegerクラスの以下の行でスローされた例外です。

Integer.class

                if (digit < 0) {
                    throw NumberFormatException.forInputString(s);
                }

例外がスローされると呼び出し元に伝播されます。このままでは数字以外が入力された場合、parseIntの行でプログラムは終了してしまいます。処理を続けたい場合、例えば、「数字以外が入力されました。」という表示をさせたい場合には次のようにtry-catch文を使います。

try-catch

        try {
            int n = Integer.parseInt(s); // String型をint型に変換
        } catch (NumberFormatException e) {
            System.out.println("数字以外が入力されました。");
        }

上記ではInteger.parseInt()メソッドの処理でスローされたNumberFormatExceptionをcatchし、”数字以外が入力されました。”という文字列をコンソールに出力しています。Integer.parseInt()メソッドでNumberFormatExceptionがスローされない場合、catch節は実行されません。

非チェック例外

Ingeter#parseInt(String s)はメソッドの宣言に「throws NumberFormatException」が付与されています。これはthrows節と呼ばれ、このメソッドがNumberFormatExceptionをスローする可能性があることを宣言しています。ですが、try-catch文の処理を書かなくてもコンパイルは出来ます。NumberFormatExceptionクラスはRuntimeExceptionクラスのサブクラスです。なので非チェック例外と呼ばれる種類の例外クラスです。非チェック例外はtry-catch文を記述しなくてもコンパイルエラーにはなりません。

RuntimeExceptionはExceptionの子クラスです。以下のような関係になってます。

Exception
└RuntimeException

例外は非チェック例外とチェック例外があります。チェック例外はExceptionクラスと、そのサブクラスのうちでRuntimeExceptionクラスのサブクラスでないものがすべてです。チェック例外がthrows節に記述されたコンストラクタ・メソッドを使う場合、try-catch文で囲む必要があります。

例えば、FileWriterのクラスのコンストラクタFileWriter(String fileName)は「throws IOException」が記述されています。この例外クラスはExceptionクラスの子クラスです。そのため、このコンストラクタを使う場合はtry-catch文の処理が必要になります。try-catch文を使わない場合、「処理されない例外の型 IOException」というコンパイルエラーになります。