例外のthrow

Revised: Jan./26th/2002: Since: Jan./27th/2002

自動的にスローされた例外を受動的にキャッチするだけではなく、明示的にスローすることもできます。たとえば、実際には例外が発生していなくても、強制的に例外をスローすることもできます。

メソッドからメソッドへのスロー

class TestThrow {
	public static void main(String args[]) {
		try{
			int i = cal(args[0], args[1]);
				//引数が二つないと例外
			System.out.println(i);
		} catch (Exception e) {
			System.out.println("main内の例外処理:" + e);
			System.out.println("0以外の整数を二つ入力してください。");
		}
	}
	static int cal(String str1, String str2) {
		int i=0,j=0;
		try {
			i=Integer.parseInt(str1);
			j=Integer.parseInt(str2);
				//	整数に直せないと例外
			return i/j;
				//0除算で例外発生
		} catch (ArithmeticException e) {
			System.out.println("メソッド内の例外処理:" + e);
			throw e;
		}
	}
}

メソッド内で、 ArithmeticException だけキャッチしてスローしています。

C:\java>javac TestThrow.java
C:\java>java TestThrow 10 3
3
C:\java>java TestThrow
main内の例外処理:java.lang.ArrayIndexOutOfBoundsException
0以外の整数を二つ入力してください。
C:\java>java TestThrow 3.14 0.01
main内の例外処理:java.lang.NumberFormatException: 3.14
0以外の整数を二つ入力してください。
C:\java>java TestThrow 5 0
メソッド内の例外処理:java.lang.ArithmeticException: / by zero
main内の例外処理:java.lang.ArithmeticException: / by zero
0以外の整数を二つ入力してください。

メソッド内部から明示的にスローされたメソッドは、呼び出しもとのメソッドでもキャッチできます。その際、スローする例外の型と、キャッチする例外の型が互換するように注意が必要です。

このサンプルでは、スローした ArithmeticExceptionException でキャッチしているので問題ありません。逆にするとコンパイルエラーが発生します。

例外の作成とスロー

例外もクラスですから、インスタンス化してオブジェクトを作成できます。このように作成された例外オブジェクトはスローで来ます。

class TestThrow2 {
	public static void main(String[] args) {
		try {
			System.out.println("実行開始");
			throw new IllegalAccessException();
		} catch (IllegalAccessException e) {
			System.out.println("例外:" + e);
			System.out.println("実行終了。");
		}
	}
}
C:\java>javac TestThrow2.java
C:\java>java TestThrow2
実行開始
例外:java.lang.IllegalAccessException
実行終了。

ここでは、標準クラスライブラリに用意された例外をインスタンス化しましたが、 Exception クラスを継承することで、自分でも独自の例外クラスを定義してインスタンス化することができます。このような自分で作った例外クラス型オブジェクトは自動的には発生しないので、 throw 文を用いて明示的に例外を発生させることが必要です。

throw と throws のサンプル

次の例は、J2SDK 1.4 API 仕様書に載っているサンプルです。

public class Junk {
	public static void main(String args[]) {
		try {
			a();
		} catch(HighLevelException e) {
			e.printStackTrace();
		}
	}
	static void a() throws HighLevelException {
		try {
			b();
		} catch(MidLevelException e) {
			throw new HighLevelException(e);
		}
	}
	static void b() throws MidLevelException {
		c();
	}
	static void c() throws MidLevelException {
		try {
			d();
		} catch(LowLevelException e) {
			throw new MidLevelException(e);
		}
	}
	static void d() throws LowLevelException {
		e();
	}
	static void e() throws LowLevelException {
		throw new LowLevelException();
	}
}
class HighLevelException extends Exception {
	HighLevelException(Throwable cause) { super(cause); }
}
class MidLevelException extends Exception {
	MidLevelException(Throwable cause)  { super(cause); }
}
class LowLevelException extends Exception {}

コンパイルして動作を確認してください。throw文とthrows節の働きが分かると思います。



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