Java 応用編 6日目

プログラム実行時に、実行を妨げる異常な事象が発生した際、プログラムに「例外」として通知する機能があります
プログラムが「例外」に対処していない場合は、プログラムは異常終了してしまいますが、「例外」に対処されていれば、通常の処理に戻ることができます
この章では「例外」に対処する処理である「例外処理」について説明をしていきます

例外を捉える

以下のようなプログラムを実行した場合、0で除算したことによるエラーが発生しプログラムが異常終了してしまいます

public class Sample{

     public static void main(String []args){
        int a = 5;
        int b = 0;
        int num = a/b;
     }
}
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at Sample.main(Sample.java:7)

そこで、異常終了しないように例外処理を書いてみたいと思います
Javaで例外処理を捕捉するにはtry(トライ)文を使い以下のように記述します
try文を使うと本来の処理の流れを分断することなく、簡潔にエラー処理を書くことができます

try{

} catch 例外{
    例外発生時の処理
}

try{
    文
}

tryの後、{}でtryブロックを指定し、例外が発生する可能性のある文を記述します

} catch 例外{
    例外発生時の処理
}

catchの後には、例外処理の対象となる例外クラスを指定し、{}で例外処理のブロックを記述します
上の例ではjava.lang.ArithmeticExceptionが発生していましたので、ArithmeticExceptionを捕捉してみます

public class Sample{
     public static void main(String []args){
         try{
            int a = 5;
            int b = 0;
            int num = a/b;
         } catch(ArithmeticException e){
             System.out.println(e);
             System.out.println("0で除算できません");
             return;
         }
     }
}
実行結果
java.lang.ArithmeticException: / by zero
0で除算できません

try‐catch文を書くことで異常終了せず通常処理に戻ることができました
例外処理を記述しておけば、エラー発生時に適切な処理を行いプログラムの続行や正常終了を目指すことができます
また、エラーが発生したときに、エラーの種類や場所、原因などの情報をログに出力したりユーザーに通知することで、問題の早期発見や解決に役立ちます

try-catch文は以下のサンプルプログラムのようにcatchを複数記述することもできます

import java.util.Scanner;

public class Sample{
	public static void main(String[] args) {
		try {
		  Scanner scanner = new Scanner(System.in);
			int sum_price = 1000;
			System.out.println("数量を入力してください");
			int count = scanner.nextInt();
			int price = sum_price / count;
			System.out.println("単価="+price);
		} catch (InputMismatchException e){
			System.out.println(e);
			System.out.println("数字を入力してください");
		} catch (ArithmeticException e) {
			System.out.println(e);
			System.out.println("数量は1以上の値を入力してください");
		} 
  }
}
実行結果
数量を入力してください
a
java.util.InputMismatchException
数字を入力してください

数量を入力してください
0
java.lang.ArithmeticException: / by zero
数量は1以上の値を入力してください

実行結果
数量を入力してください
10
単価=100
Scanner scanner = new Scanner(System.in);

キーボードから値を取得する際に使用します
詳細は応用編 7日目で説明します

int count = scanner.nextInt();

キーボードから取得した値を整数値として扱い、変数countに代入しています
整数に変換できない場合、java.util.InputMismatchExceptionエラーが発生するので、catch文でエラーを捕捉するcatch文を追加しています

また、あらゆる例外を処理したい場合にはExceptionという例外を指定することができます
InputMismatchExceptionもArithmeticExceptionもExceptionクラスの子孫であるため、捕捉する例外が増えてもcatchブロックを増やすことなく例外を捕捉することができます

import java.util.Scanner;

public class Sample{
	public static void main(String[] args) {
		try {
			Scanner scanner = new Scanner(System.in);
			int sum_price = 1000;
			System.out.println("数量を入力してください");
			int count = scanner.nextInt();
			int price = sum_price / count;
			System.out.println("単価="+price);
		} catch (Exception e) {
			System.out.println(e);
			System.out.println("入力値に問題があります");
		}
  }
}

例外を意図的に発生させる

「例外を捉える」では、例外を捉え処理する方法を説明してきました
一方、例外を意図的に発生させることもできます

throw 例外インスタンス

throw文を使い例外を発生させます
例外の部分には発生させたい例外クラスや例外オブジェクトを指定することにより、エラーに関する情報を提供することができます
mainメソッドで呼び出されたサブメソッド内での例外を、呼び出し側のmainメソッドに伝播させ、例外に対する処置を呼び出し側のmainメソッドにゆだねるような使い方ができます

以下にthrow文を使ったサンプルプログラムを示します

  • 例外の伝播

例外を呼び出し元に伝播させます

    public class Sample{
      static int div(int a,int b){
        try{
             return a/b;
        } catch(Exception e){
             throw e;
        }
      }

      public static void main(String []args){
        try{
            int a = 5;
            int b = 0;
            int num = div(a,b);
        } catch(Exception e){
            System.out.println(e);
            System.out.println("0で除算できません");
            return;
        }
     }
   }

  • Exceptionを発生させる
   public class Sample{
    static int my_function(int value){
      if (value < 0){
        throw new IllegalArgumentException("値は0以上である必要があります");
      }
      return value * value;
    }

    public static void main(String []args){
      try{
        int a = -1;
        int num = my_function(a);
        System.out.println("num=" + num);
      } catch(Exception e){
        System.out.println(e.getMessage());
        return;
      }
    }
 実行結果
 値は0以上である必要があります

このサンプルプログラムは、my_functionの引数が負の値の場合、例外を発生させています

   throw new IllegalArgumentException("値は0以上である必要があります");

この行で、例外を発生させ、例外の内容を格納しています

  • 例外クラスを独自に定義する

例外クラスを定義する場合、Exceptionクラスを継承する必要があります

   class MyErrorException extends Exception{
	  // エラーメッセージを受け取るコンストラクタ
	  public MyErrorException(String msg) {
		  super(msg); 
	  }
   }
   public class Sample{
     public static void main(String []args){
          try{
            int a = -1;
            if (a<0) {
            	 throw new MyErrorException("値は0以上である必要があります");
            }
            int num = a * a;
            System.out.println("num=" + num);
         } catch(Exception e){
             System.out.println(e.getMessage());
             return;
         }
     }
   }
実行結果
値は0以上である必要があります

演習問題

  1. Integer.parseIntメソッドを使い、文字列を整数に変換してみましょう
    また、以下のURLを参考に、例外処理を組み込んでみましょう
    https://docs.oracle.com/javase/jp/12/docs/api/java.base/java/lang/Integer.html#parseInt(java.lang.String)
  2. 整数型の配列を用意し、要素数以上の添え字に値を代入するプログラムを、例外処理を組み込んで作成してみましょう
   実行結果
   Index 5 out of bounds for length 5

コメント

この記事へのコメントはありません。

関連記事

【Java】簡単操作でサーブレット環境を構築!【動画あり】

Python 応用編 5日目

Java 応用編 7日目

PAGE TOP