ErrorとException
Javaでは例外処理の対象はError、Exceptionの2種類です。
さらに詳しく言えばExceptionはコンパイラーが例外処理が記述されていることをチャックする検査例外であるのに対し、ExceptionのサブクラスであるRuntimeExceptionは、例外自体が発生しないようにプログラマがロジックを工夫することが期待されているためコンパイラーは例外処理の記述をチェックしない事。
そして、例外処理の記述法などを説明しました。
ここでは、それらError、ExceptionとしてJavaが用意している例外クラスを説明し、さらにそれらを踏まえて独自に例外クラスを作って例外処理する方法を説明します。
基本的には、このような事態が発生しないようにプログラムを十分テストしたり、実行環境を確認し、整えておく必要があります。
コンパイル時点で存在していたクラスが、見つからない。
例えば、Integerクラスのparselntメソッドに文字として英数字以外を渡す。
public class Main01 { public static void main(String[] args) { String[] str = new String[1]; for(String s :str) { System.out.println(s + " , " + str[1]); } } }
>java Main01 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 1 at Main01.main(Main01.java:5) >
public class Main03 { public static void main(String[] args) { String str = "string"; System.out.println(str.charAt(6)); } }
>java Main03 Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 6 at java.lang.String.charAt(Unknown Source) at Main03.main(Main03.java:4) >
配列変数がnullなのに、配列のサイズを調べる。
public class Main02 { public static void main(String[] args) { String[][] str = null; System.out.println(str.length); } }
>java Main02 Exception in thread "main" java.lang.NullPointerException at Main02.main(Main02.java:4) >
以上はJavaが用意している例外クラスの一部です。その他の例外クラスについてはJava APIドキュメントで確認することが出来ます。
この様に数々の例外クラスが用意されていますが、プログラム開発上独自に値の確認をしたい変数などあるでしょう。これらの確認に自分で独自の例外を定義して、例外処理の仕組みを使えばスマートに不具合への対処を組み込むことが出来ます。
参考例として、映画館のチケットの代金を計算してみましょう。
通常料金は1800円として、夜10:00(22:00)からをレイトショーとして1300円に割引します。
上映は朝9:00から始まるとして、希望の上映開始時間を整数で入力してもらいます。
入力された数字が9より少なかったり、24以上だったりした場合は再入力。また、数字以外の文字が入力された場合も再入力してもらいます。
時間の入力範囲チェックにはRuntimeExceptionのサブクラスとして独自例外:OutOfTimeRangeExceptionを作成し、9~23以外の入力があった場合にそれを発行し、数字以外の誤文字入力は実行時例外として通知されるNumberFormatExceptionをメインクラスでそれぞれ例外処理しています。
public class OutOfTimeRangeException extends RuntimeException { }
レイトショー割引も考慮してチケット代金を求めるHowMuchIsTheFee
import java.util.Scanner; public class HowMuchIsTheFee { public static void main(String[] args) { HowMuchIsTheFee hmticket = new HowMuchIsTheFee(); int ticketFee = 1800; boolean lateShow = hmticket.isLateShow(); System.out.print("チケット代は"); if( lateShow ) { System.out.print("レイトショー割引で"); ticketFee = 1300; } System.out.println(ticketFee + "円です。"); } public boolean isLateShow() { //22時以降はレイトショーで割引あり。 while( true ) { Scanner sc = new Scanner(System.in); System.out.print("購入するチケットは何時の回ですか?\n9以上24より少ない数字を入力してください。:"); String keyString = sc.next(); try { int ticketTime = Integer.parseInt(keyString); if(ticketTime<9 || ticketTime>=24) throw new OutOfTimeRangeException(); if(ticketTime>=22 && ticketTime<24) return true; return false; } catch (NumberFormatException e) { System.out.print("整数値以外の入力がありました。"); } catch (OutOfTimeRangeException e) { System.out.print("入力された数字に誤りがあります。"); } finally { System.out.println("再入力してください。\n"); } } } }
ハイライトされたisLateShowメソッドが、希望の上映開始時間を受付し、入力値チェックを行い入力誤りがあれば例外処理の中でエラーメッセージを出し、入力に誤りが無ければレイトショーに該当するか否かを論理値としています。
実行結果は以下のようになります。
>java HowMuchIsTheFee 購入するチケットは何時の回ですか? 9以上24より少ない数字を入力してください。:aa 整数値以外の入力がありました。再入力してください。 購入するチケットは何時の回ですか? 9以上24より少ない数字を入力してください。:8 入力された数字に誤りがあります。再入力してください。 購入するチケットは何時の回ですか? 9以上24より少ない数字を入力してください。:24 入力された数字に誤りがあります。再入力してください。 購入するチケットは何時の回ですか? 9以上24より少ない数字を入力してください。:10 再入力してください。 チケット代は1800円です。 >java HowMuchIsTheFee 購入するチケットは何時の回ですか? 9以上24より少ない数字を入力してください。:23 再入力してください。 チケット代はレイトショー割引で1300円です。 >