S-JIS[2003-07-06] 変更履歴
throwTest.java
//例外1 class Exception1 extends Exception{ } //例外2 class Exception2 extends Exception{ } public class throwTest{ //テスト開始---------------------------------------------------- public static void main(String[] args){ System.out.println("main-start"); //実行順1⇒ try{ test(); //実行順2⇒ }catch(Exception1 e){ System.out.println("main:Exception1をcatch"); e.printStackTrace(); }catch(Exception2 e){ System.out.println("main:Exception2をcatch"); //実行順9⇒ e.printStackTrace(); }catch(Exception e){ System.out.println("main:Exceptionをcatch"); e.printStackTrace(); }finally{ System.out.println("main:finally"); //実行順10⇒ } System.out.println("main-end"); //実行順11 } //1つ目-------------------------------------------------------- static void test() throws Exception{ System.out.println("test-start"); //実行順3⇒ try{ start(); //実行順4⇒ }catch(Exception1 e){ System.out.println("test:Exception1をcatch"); //実行順6⇒ // System.out.println("test:自分自身をthrow"); throw e; System.out.println("test:Exception2をthrow"); throw new Exception2(); //実行順7⇒ }catch(Exception2 e){ System.out.println("test:Exception2をcatch"); throw e; }catch(Exception e){ System.out.println("test:Exceptionをcatch"); }finally{ System.out.println("test:finally"); //実行順8⇒ } System.out.println("test-end"); //ここは実行されない } //例外発生----------------------------------------------------- static void start() throws Exception{ System.out.println("start:Exception1をthrow"); throw new Exception1(); //実行順5⇒ } }
実行結果
> javac throwTest.java > java throwTest main-start test-start start:Exception1をthrow test:Exception1をcatch test:Exception2をthrow test:finally main:Exception2をcatch Exception2 at throwTest.test(throwTest.java:44) at throwTest.main(throwTest.java:17) main:finally main-end >
処理は、main()がtest()を呼び出し、test()がstart()を呼び出す。start()は例外をまず発生させる。
start()が投げた例外1はtest()のException1でキャッチされる。
ここで「throw e」を実行すると、キャッチした例外そのもの(例外1)が
tryの外に投げられる。
「throw new Exception2()」の場合だと、新しく例外2を作って、それをtryの外に投げる。
いずれの場合でも、あくまでtryの外に投げるのであり、後続のキャッチが捕まえるわけではない。
test()で再度投げられた例外は、main()のtryでキャッチされる。
ちなみに、printStackTrace()は、例外が投げられた箇所からのメソッドの呼び出しの履歴を表示する命令。
通常、これはJavaVMが行っているが、例外を自分でキャッチした場合はJavaVMまで戻らないので、スタックを見たいのであれば自分で呼び出してやる必要がある。
さらに、getStackTrace()という関数もある。これを使うと、呼び出し履歴を配列の形で取得できる。
ただし、関数内部で配列のコピーを行っているらしく、少々重いので大量に使うのは考えた方がいいかも。