こんにちは。「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」というコンパイルエラーになります。