単純な例外処理

Revised: Feb./15th/2003: Since: Jan./27th/2002

ここでは単純な例外処理のサンプルを示します。

ArrayIndexOutOfBoudsException

java.lang.Object
  |
  +--java.lang.Throwable
        |
        +--java.lang.Exception
              |
              +--java.lang.RuntimeException
                    |
                    +--java.lang.IndexOutOfBoundsException
                          |
                          +--java.lang.ArrayIndexOutOfBoundsException

不正なインデックスを使って配列がアクセスされたことを示します。

class TestExcep1 {
	public static void main(String[] args) {
		System.out.println("実行開始。");
		try {
			System.out.println(args[0]);
			System.out.println("tryブロック終了");
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("例外:" + e);
			System.out.println("引数を一つ入力してください。");
		}
		System.out.println("実行終了。");
	}
}
C:\java>javac TestExcep1.java
C:\java>java TestExcep1
実行開始。
例外:java.lang.ArrayIndexOutOfBoundsException
引数を一つ入力してください。
実行終了。

引数の配列の個数が正しくないために起こった例外です。この場合は、ロジックで容易に回避できます:

if (args.length != 1) {
	System.out.println("引数を一つ入力してください。");
	return;
}

配列 args[] の要素数が1でない場合に true となり、ブロック内が実行されます。

NumberFormatException

java.lang.Object
  |
  +--java.lang.Throwable
        |
        +--java.lang.Exception
              |
              +--java.lang.RuntimeException
                    |
                    +--java.lang.IllegalArgumentException
                          |
                          +--java.lang.NumberFormatException

文字列を数値型に変換しようとしたとき、文字列の形式が正しくない場合にスローされます。

class TestExcep2 {
	public static void main(String[] args) {
		System.out.println("実行開始。");
		try {
			int i;
			i=Integer.parseInt(args[0]);
				//引数がないか、整数に直せなかったら例外がスローされる
			System.out.println(i*100);
			System.out.println("tryブロック終了");
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("例外:" + e);
			System.out.println("引数を一つ入力してください。");
		} catch (NumberFormatException e) {
			System.out.println("例外:" + e);
			System.out.println("引数を整数で入力してください。");
		}
		System.out.println("実行終了。");
	}
}
C:\java>javac TestExcep2.java
C:\java>java TestExcep2
実行開始。
例外:java.lang.ArrayIndexOutOfBoundsException
引数を一つ入力してください。
実行終了。
C:\java>java TestExcep2 3.14
実行開始。
例外:java.lang.NumberFormatException: 3.14
引数を整数で入力してください。
実行終了。

ArithmeticException

java.lang.Object
  |
  +--java.lang.Throwable
        |
        +--java.lang.Exception
              |
              +--java.lang.RuntimeException
                    |
                    +--java.lang.ArithmeticException

算術計算で例外的条件が発生した場合にスローされます。たとえば、整数を「ゼロで除算」するとこのクラスのインスタンスがスローされます。

class TestExcep2 {
	public static void main(String[] args) {
		System.out.println("実行開始。");
		try{
			int i, j=100;
			System.out.println("j: " + j);
			i=Integer.parseInt(args[0]);
			System.out.println("j/i: " + j/i);
				//0で割ると例外がスローされる
			System.out.println("tryブロック終了");
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("例外:" + e);
			System.out.println("引数を一つ入力してください。");
		} catch (NumberFormatException e) {
			System.out.println("例外:" + e);
			System.out.println("引数を整数で入力してください。");
		} catch (ArithmeticException e) {
			System.out.println("例外:" + e);
			System.out.println("引数を0以外の整数で入力してください。");
		}
		System.out.println("実行終了。");
	}
}

引数が与えられない場合は、最初の catch ブロックにつかまります。引数は与えられるけど、整数に変換できない場合は、二番目の catch ブロックにつかまります。引数が与えられて整数に変換できるけど、それがゼロであった場合は、ゼロ割りになって三番目の catch ブロックにつかまります。

C:\java>javac TestExcep3.java
C:\java>java TestExcep3 0
実行開始。
j: 100
例外:java.lang.ArithmeticException: / by zero
引数を0以外の整数で入力してください。
実行終了。
C:\java>java TestExcep3 -5
実行開始。
j: 100
j/i: -20
tryブロック終了
実行終了。

Exception

発生する例外を全てキャッチしたい場合は、 Exception 型でキャッチすることができます。

全ての例外クラスは Exception クラスをスーパークラスに持ちます。したがって、全ての例外クラスを Exception 型として catch できるのです。

class TestExcep4 {
	public static void main(String[] args) {
		String str=null;
		try {
			System.out.println(str.length());
		} catch (Exception e) {
			System.out.println("例外:" + e);
		}
	}
}

このサンプルでは、 null 値が代入された文字列型オブジェクトに length() メソッドを要求しています。文字列が代入されていれば、文字の個数を返しますが、 null 値の場合は、例外 NullPointException が発生します。

C:\java>javac TestExcep4.java
C:\java>java TestExcep4
例外:java.lang.NullPointerException

このサンプルでは、 NullPointerException という例外が発生していますが、 Exception 型の例外としてきちんと拾われています。全ての例外は Exception から派生しているので、自動型変換されてキャッチされるのです。

Exception 型は全ての例外オブジェクトと代入互換なので、最後に記述する必要があります。Exception 型を最初に記述してしまうと、全ての例外オブジェクトがそこでキャッチされてしまうので、後続の catch ブロックには絶対に制御が移らないのです。先ほどの ArithmaticException のキャッチの例を挙げると、 Exception は最後に記述すべきです。

class TestExcep2 {
	public static void main(String[] args) {
		System.out.println("実行開始。");
		try{
			int i, j=100;
			System.out.println("j: " + j);
			i=Integer.parseInt(args[0]);
			System.out.println("j/i: " + j/i);
				//0で割ると例外がスローされる
			System.out.println("tryブロック終了");
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("例外:" + e);
			System.out.println("引数を一つ入力してください。");
		} catch (NumberFormatException e) {
			System.out.println("例外:" + e);
			System.out.println("引数を整数で入力してください。");
		} catch (ArithmeticException e) {
			System.out.println("例外:" + e);
			System.out.println("引数を0以外の整数で入力してください。");
		} catch (Exception e) {
			System.out.println("なんらかの例外が発生しました。");
			e.printStackTrace();
		}
		System.out.println("実行終了。");
	}
}


Copyright © 2001-2003 SUGAI, Manabu. All Rights Reserved.
SEO [PR] !uO z[y[WJ Cu