例外クラス
前節で見たように、Javaで用意されているメソッドで発生する可能性があるものは、ライブラリに説明が載せられているので、その例外クラス名を使用して例外処理を記述できます。例外処理はそれ以外にも、自分で例外クラスを作って、発生(スロー)させることもできます。
例外クラスを作成するには次のように記述します。
自分で作った例外クラスは自分でスローしなくてはなりません。例外をスローするには次のように記述します。
ここで、先回作成したBusクラスを修正しましょう。今までは、乗車や降車をするときに走っていないかどうかなどを調べ、異常がある場合はその旨のメッセージを返すように作ってきました。それを例外処理に書き換えましょう。
○ ファイル
次のようにファイルを作成してください。
ファイル名 |
WarningException.java |
サンプルダウンロード
○ プログラム
例外を表すクラスを作成しましょう。Exceptionクラスを継承した次のようなクラスを作成してください。
- public class WarningException extends Exception{
- public WarningException(String error){
- super(error);
- }
- }
○ 解説
1行目でスーパークラスにExceptionクラスを指定しています。それにより今回作成したWarningExceptionクラスはスローしてキャッチすることができるようになります。例外を表すクラスは多くの場合~Exceptionのように名前を付けます。
2~4行目ではコンストラクタを定義しています。このコンストラクタはインスタンス生成時にスーパークラスであるExceptionクラスのコンストラクタを呼び出しています。引数として受け取ったエラーメッセージをさらに引数として渡しています。これによりgetMessageメソッドで、引数で指定したエラーメッセージが参照できるようになります。
○ プログラム
次にBusクラスを変更しましょう。次のように修正してください。
Bus.java
- class Bus extends Car{
- //フィールド==========
- private int salesAmount; //運賃
- private int passengerNumber; //乗客人数
- //コンストラクタ==========
- public Bus(){
- this(100);
- }
- public Bus(double gas){
- super(gas);
- this.salesAmount = 0;
- this.passengerNumber = 0;
- }
- //メソッド==========
- //乗車させるメソッド
- public void rideToBus(int fare) throws WarningException{
- //走行中かどうか
- if(this.getSpeed() != 0){
- throw new WarningException("停車してください。");
- }
- //満席かどうか
- if(this.passengerNumber >= 50){
- throw new WarningException("満席のため、乗車できません。");
- }
- //料金と、乗車人数を加算
- this.salesAmount += fare;
- this.passengerNumber++;
- }
- //降車させるメソッド
- public void getOffBus() throws WarningException{
- //走行中かどうか
- if(this.getSpeed() != 0){
- throw new WarningException("停車してください。");
- }
- //乗客がいるかどうか
- if(this.passengerNumber == 0){
- throw new WarningException("乗客はいません。");
- }
- //乗車人数を減算
- this.passengerNumber--;
- }
- //フィールドのgetterの準備
- public int getSalesAmount(){
- return this.salesAmount;
- }
- public int getPassengerNumber(){
- return this.passengerNumber;
- }
- //加速させるメソッド
- public void speedUp(int sp){
- //スピードが60km以下なら加速する
- if((this.getSpeed() + sp) <= 60){
- super.speedUp(sp);
- }
- }
- }
○ 解説
19、36行目では、処理の中でエラーが発生した場合は文字列を返す仕組みから例外をスローする仕組みに変更するため、戻すデータがなくなりました。そのため、戻り値の型をstringからvoidに変更しています。また、メソッドの処理内でWarningExceptionがスローされる可能性があるため、throws文を指定して、呼び出し側で処理をさせるようにしています。
22、27、39、44行目では、エラーが発生した場合にその時のエラーメッセージをreturn文で返していましたが、throw文を使って例外をスローさせるように変更しました。
○ プログラム
次にmainソッドを変更しましょう。Run2クラスを次のように修正してください。
Run2.java
- import java.io.*;
- public class Run2{
- //車の状態を表示するメソッド
- public static void showData(Bus bus){
- System.out.println("スピード:" + bus.getSpeed() + "km");
- System.out.println("ガソリン:" + bus.getGas() + "L");
- System.out.println("売上金額:" + bus.getSalesAmount() + "円");
- System.out.println("乗車人数:" + bus.getPassengerNumber() + "人");
- }
- public static void main(String[] args){
- //インスタンスを生成する
- Bus bus = new Bus(150);
- //現在の状態を表示する
- showData(bus);
- //キーボード入力の準備をする
- BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
- while(true){
- try{
- //操作を入力
- System.out.print("1)加速 2)減速 3)給油 7)乗車 8)降車 9)終了:");
- String inputdata = br.readLine();
- //操作によって分岐する
- switch (inputdata){
- case "1":
- //加速する
- bus.speedUp(5);
- showData(bus);
- break;
- case "2":
- //減速する
- bus.speedDown(5);
- showData(bus);
- break;
- case "3":
- //給油する
- bus.setGas(80);
- showData(bus);
- break;
- case "7":
- //乗車する
- bus.rideToBus(200);
- showData(bus);
- break;
- case "8":
- //降車する
- bus.getOffBus();
- showData(bus);
- break;
- case "9":
- //プログラムを終了する
- return;
- }
- }catch(WarningException e){
- System.out.println(e.getMessage());
- }catch(Exception e){
- System.out.println("エラーが発生しました。");
- }
- }
- }
- }
○ 解説
23~63行目では、try~catch文が記述されています。47、52行目で、バスオブジェクトのメソッドが呼び出されると、状態によって例外(WarningException)がスローされてきます。その場合は、59行目でキャッチされ、60行目の処理が行われます。61行目はWarningException以外がtry文の中でスローされたときにキャッチされます。
catch文は複数指定することができます。try文でスローされた例外オブジェクトに応じてキャッチされます。それぞれのcatch文が上から順に評価されていきます。そのため、Exception型のcatchは最後に指定しないとエラーとなります。上の方にExeption型の指定をすると必ずそこでキャッチされ、下に指定したcatch文は使われないからです。
前へ 次へ