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以外の整数を二つ入力してください。
メソッド内部から明示的にスローされたメソッドは、呼び出しもとのメソッドでもキャッチできます。その際、スローする例外の型と、キャッチする例外の型が互換するように注意が必要です。
このサンプルでは、スローした ArithmeticException を Exception でキャッチしているので問題ありません。逆にするとコンパイルエラーが発生します。
例外もクラスですから、インスタンス化してオブジェクトを作成できます。このように作成された例外オブジェクトはスローで来ます。
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 文を用いて明示的に例外を発生させることが必要です。
次の例は、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節の働きが分かると思います。