例外クラス

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

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

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

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

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

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

○ ファイル

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

ファイル名 WarningException.java

サンプルダウンロード

○ プログラム

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

  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. 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.  }
  42.  //フィールドのgetterの準備
  43.  public int getSalesAmount(){
  44.   return this.salesAmount;
  45.  }
  46.  public int getPassengerNumber(){
  47.   return this.passengerNumber;
  48.  }
  49.  //加速させるメソッド
  50.   public void speedUp(int sp){
  51.   //スピードが60km以下なら加速する
  52.   if((this.getSpeed() + sp) <= 60){
  53.    super.speedUp(sp);
  54.   }
  55.  }
  56. }

○ 解説

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

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

○ プログラム

 次にmainソッドを変更しましょう。Run2クラスを次のように修正してください。

Run2.java

  1. import java.io.*;
  2. public class Run2{
  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. }

○ 解説

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

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

前へ   次へ