例外クラス

前節で見たように、Javaで用意されているメソッドで発生する可能性があるものは、ライブラリに説明が載せられているので、その例外クラス名を使用して例外処理を記述できます。例外処理はそれ以外にも、自分で例外クラスを作って、発生(スロー)させることもできます。

例外クラスを作成するには次のように記述します。

例外クラス定義の書式
class 例外クラス名 extends Exception{
 
}

自分で作った例外クラスは自分でスローしなくてはなりません。例外をスローするには次のように記述します。

例外クラススローの書式
throw 例外オブジェクト;

ここで、先回作成したBusクラスを修正しましょう。今までは、乗車や降車をするときに走っていないかどうかなどを調べ、異常がある場合はその旨のメッセージを返すように作ってきました。それを例外処理に書き換えましょう。

○ ファイル

次のようにファイルを作成してください。

ファイル名 WarningException.java

サンプルダウンロード

○ プログラム

例外を表すクラスを作成しましょう。Exceptionクラスを継承した次のようなクラスを作成してください。

WarningException.java

  1. public class WarningException extends Exception{
  2.     public WarningException(String error){
  3.         super(error);
  4.     }
  5. }

○ 解説

1行目では、スーパークラスにExceptionクラスを指定しています。それにより、今回作成したWarningExceptionクラスは、スローしてキャッチすることができるようになります。例外を表すクラスは多くの場合~Exceptionのように名前を付けます。

2~4行目では、コンストラクターを定義しています。このコンストラクターはインスタンス生成時にスーパークラスであるExceptionクラスのコンストラクターを呼び出しています。引数として受け取ったエラーメッセージをさらに引数として渡しています。これによりgetMessageメソッドで、引数で指定したエラーメッセージが参照できるようになります。

○ プログラム

次にBusクラスを変更しましょう。次のように修正してください。

サンプルダウンロード

Bus.java

  1. public class Bus extends Car{
  2.     //フィールド
  3.     private int salesAmount;            //運賃
  4.     private int passengerNumber;        //乗客人数
  5.     //コンストラクター
  6.     public Bus(){
  7.         this(100);
  8.     }
  9.     public Bus(double gas){
  10.         super(gas);
  11.         this.salesAmount = 0;
  12.         this.passengerNumber = 0;
  13.     }
  14.     //メソッド
  15.     //乗車させるメソッド
  16.     public void rideToBus(int fare) throws WarningException{
  17.         //走行中かどうか
  18.         if(this.getSpeed() != 0){
  19.             throw new WarningException("停車してください。");
  20.         }
  21.         //満席かどうか
  22.         if(this.passengerNumber >= 50){
  23.             throw new WarningException("満席のため、乗車できません。");
  24.         }
  25.         //料金と、乗車人数を加算
  26.         this.salesAmount += fare;
  27.         this.passengerNumber++;
  28.     }
  29.     //降車させるメソッド
  30.     public void getOffBus() throws WarningException{
  31.         //走行中かどうか
  32.         if(this.getSpeed() != 0){
  33.             throw new WarningException("停車してください。");
  34.         }
  35.         //乗客がいるかどうか
  36.         if(this.passengerNumber == 0){
  37.             throw new WarningException("乗客はいません。");
  38.         }
  39.         //乗車人数を減算
  40.         this.passengerNumber--;
  41.     }
(省略・・・)

○ 解説

19、36行目では、処理の中でエラーが発生した場合は文字列を返す仕組みから例外をスローする仕組みに変更するため、戻すデータがなくなりました。そのため、戻り値の型をstringからvoidに変更しています。また、メソッドの処理内でWarningExceptionがスローされる可能性があるため、throws文を指定して、呼び出し側で処理をさせるようにしています。

22、27、39、44行目では、エラーが発生した場合にその時のエラーメッセージをreturn文で返していましたが、throw文を使って例外をスローさせるように変更しました。

○ ファイル

BusTest.javaをコピーして、次のようにファイルを作成してください。

ファイル名 BusTest2.java

サンプルダウンロード

○ プログラム

次のように修正してください。

BusTest2.java

  1. import java.io.*;
  2. public class BusTest2{
  3.     //車の状態を表示するメソッド
  4.     public static void showData(Bus bus){
  5.         System.out.println("スピード:" + bus.getSpeed() + "km");
  6.         System.out.println("ガソリン:" + bus.getGas() + "L");
  7.         System.out.println("売上金額:" + bus.getSalesAmount() + "円");
  8.         System.out.println("乗車人数:" + bus.getPassengerNumber() + "人");
  9.     }
  10.     public static void main(String[] args){
  11.         //インスタンスを生成する
  12.         Bus bus = new Bus(150);
  13.         //現在の状態を表示する
  14.         showData(bus);
  15.         //キーボード入力の準備をする
  16.         BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  17.         while(true){
  18.             try{
  19.                 //操作を入力
  20.                 System.out.print("1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:");
  21.                 String inputdata = br.readLine();
  22.                 //操作によって分岐する
  23.                 switch (inputdata){
  24.                     case "1":
  25.                         //加速する
  26.                         bus.speedUp(5);
  27.                         showData(bus);
  28.                         break;
  29.                     case "2":
  30.                         //減速する
  31.                         bus.speedDown(5);
  32.                         showData(bus);
  33.                         break;
  34.                     case "3":
  35.                         //給油する
  36.                         bus.setGas(80);
  37.                         showData(bus);
  38.                         break;
  39.                     case "7":
  40.                         //乗車する
  41.                         bus.rideToBus(200);
  42.                         showData(bus);
  43.                         break;
  44.                     case "8":
  45.                         //降車する
  46.                         bus.getOffBus();
  47.                         showData(bus);
  48.                         break;
  49.                     case "9":
  50.                         //プログラムを終了する
  51.                         return;
  52.                 }
  53.             }catch(WarningException e){
  54.                 System.out.println(e.getMessage());
  55.             }catch(Exception e){
  56.                 System.out.println("エラーが発生しました。");
  57.             }
  58.         }
  59.     }
  60. }

○ コンパイルと実行

C:¥work>javac BusTest2.java
C:¥work>java BusTest2
スピード:0km
ガソリン:150.0L
売上金額:0円
乗車人数:0人
1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:1
スピード:5km
ガソリン:149.5L
売上金額:0円
乗車人数:0人
1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:7
停車してください。
1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:2
スピード:0km
ガソリン:149.5L
売上金額:0円
乗車人数:0人
1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:7
スピード:0km
ガソリン:149.5L
売上金額:200円
乗車人数:1人
1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:1
スピード:5km
ガソリン:149.0L
売上金額:200円
乗車人数:1人
1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:8
停車してください。
1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:2
スピード:0km
ガソリン:149.0L
売上金額:200円
乗車人数:1人
1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:8
スピード:0km
ガソリン:149.0L
売上金額:200円
乗車人数:0人
1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:8
乗客はいません。
1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:9

C:¥work>

○ 解説

23~63行目では、try~catch文が記述されています。47、52行目で、バスオブジェクトのメソッドが呼び出されると、状態によって例外(WarningException)がスローされてきます。その場合は、59行目でキャッチされ、60行目の処理が行われます。61行目はWarningException以外がtry文の中でスローされたときにキャッチされます。

catch文は複数指定することができます。try文でスローされた例外オブジェクトに応じてキャッチされます。それぞれのcatch文が上から順に評価されていきます。そのため、Exception型のcatchは最後に指定しないとエラーとなります。上の方にExeption型の指定をすると必ずそこでキャッチされ、下に指定したcatch文は使われないからです。

前へ   次へ