try-catch printStackTrace - Exception(例外) - 萌えJava超入門
第十九章 Exception(例外)

try-catch

スローされた例外をキャッチして、具体的な例外処理を記述します。


  try{
      //例外をスローする可能性がある処理
  }catch(Exception e){
      //例外がスローされた場合の処理
  }

目次

1.例外をスローさせる


以下のサンプルコードは、要素数3の配列に対して、
インデックス3の要素を参照しています。
要素数3の配列の最終要素はインデックス2ですから、例外をスローします。

基本的に前のページで紹介した
ソースと同じだ。
//Sample19_11.java
class Sample19_11{
    public static void main(String[] args){

        int[] intArray = {
            123,
            456,
            789
        };

        System.out.println(intArray[3]);//ココで例外スロー
        System.out.println("complete");
    }
}

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Sample19_11.java
ws>java Sample19_11
Exception in thread "main"
 java.lang.ArrayIndexOutOfBoundsException: 3
        at Sample19_11.main(Sample19_11.java:11)


ArrayIndexOutOfBoundsExceptionという例外をスローしました。
例外の一種で、RuntimeExceptionクラスのサブクラスになります。
この例外は非チェック例外なので、例外処理が無くてもコンパイルは通りました。

でも実行すると、最後の「complete」の表示がありません。
例外によって強制終了してしまいました。



2.例外処理 try-catch の使い方


例外処理とは
例外のスローに備えた処理のことを例外処理といいます。

そうね。
この前聞いたわ。
この例外に備えた処理を
実際に書いてみよう。
try-catch という方法を使ってみましょう。
try-catch は例外処理の一種です。
例外がスローされた場合の具体的な処理を catchブロックに記述します。

try-catchの書式
  try{
      //例外をスローする可能性がある処理
  }catch(Exception e){
      //例外がスローされた場合の処理
  }
e は、Exceptionクラス(又はそのサブクラス)の変数
必要に応じて Exceptionクラスのサブクラスを import してください。

スローされる例外の種類が複数ある場合には、
スローされた例外の種類に応じて、例外処理を記述することができます。

try-catch の書き方 複数の例外がある場合
 try{
   //例外をスローする可能性がある処理
 } catch(sub01Exception e1)
   //sub01Exceptionをキャッチした場合の処理
 } catch(sub02Exception e2)
   //sub02Exceptionをキャッチした場合の処理
 } catch(sub03Exception e3)
   //sub03Exceptionをキャッチした場合の処理
 }
sub01Exception sub02Exception sub03Exception は架空の例外です。

書式の説明
  1. tryブロックの中に、「例外をスローする可能性がある処理」を記述します。
  2. 例外がスローされると tryブロックの処理は中断されて、
    例外の型に対応した catchブロックの処理が実行されます。
  3. catchの引数(ここでは e)には、スロー(throw)された Exceptionクラス(又はそのサブクラス)のインスタンスが代入されます。
    これを「例外をキャッチする」と言います。
    catchの引数名には、慣習として「e」が使用されることが多いです。
  4. この変数 eのスコープは catchブロック内のみです。
  5. catchブロックの中が実行されます。
  6. catchブロック実行後は、強制終了せずに、続きを実行します。
  throw については後述します。

try-catch のブロックは変数のスコープに影響します。
必要に応じてブロックの外で宣言しましょう。



3.try-catch の使用例

Sample19_11に、try-catchで
例外処理を追加してみた。
//Sample19_12.java
class Sample19_12{
    public static void main(String[] args){

        int[] intArray = {
            123,
            456,
            789
        };

        try{
            System.out.println(intArray[3]);
        }catch(ArrayIndexOutOfBoundsException e){ //1
            System.out.println("catch block"); //2
            System.out.println(e);//例外の表示
        }

        System.out.println("complete"); //3
    }
}

コマンドライン
ws>javac -encoding UTF-8 Sample19_12.java
ws>java Sample19_12
catch block
java.lang.ArrayIndexOutOfBoundsException: 3  ←例外の表示
complete


  1. tryブロック内で、Java仮想マシンから
       例外 ArrayIndexOutOfBoundsException がスローされました。
  2. 例外がスローされたので catchブロックが実行されました。
    catch block」が表示されて、 エラーの種類が表示されました。
  3. 強制終了はせずに「complete」が表示されました。
System.out.println(intArray[3]); は実行できませんでしたが、
その後強制終了されることなく処理を続けたことがわかります。

お~。
例外が出ても
続けられるんすね。
ただ、tryブロックの中の処理は
途中で止めてしまった。
続けられるのは分かったけど、
続けていいのか悪いのか、
場合によっては疑問よね。
その通り。
例外をすべてキャッチする必要はない。
あえて強制終了させるのも選択肢だ。


4.try-catch は if-else文に似ている?

ヒントになるかわかりませんが、少し補足です。

try-catch は、「処理を分岐する」という点で if-else文 に少し似ています。

特徴は以下のような部分です。
if-else は、booleanによって処理を分岐しますが、
try-catch は、例外の有無と種類で処理を分岐します。

if-else は、
   初めに booleanによる分岐が行われて、実行される処理が決定しますが、
try-catch は、
   例外がスローされるまでの間、tryの中を実行し続けます。
   常に例外が監視されていて、例外がスローされた時点で、catchに分岐します。

Exception の種類が煩わしい
かもしれないが、
処理の流れはただの分岐なんだ。


5. Exception.printStackTraceメソッド


printStackTraceメソッドは、Exceptionクラスのインスタンスメソッドです。
(厳密には、java.lang.Throwableクラスの から継承しています。)
     ご参照→ クラスの継承関係
printStackTraceメソッドは、例外の詳細なメッセージを表示します。
以下の Sample19_13 のように、catchブロックの中で使用すると。
スローされた例外の情報がコマンドラインに表示されます。

書式
Exception#.printStackTrace();
Exception# は Exceptionクラスのインスタンスです。

デバッグに便利なのはこれだ。
例外がスローされるべきでないときに使おう。
//Sample19_13.java
class Sample19_13{
    public static void main(String[] args){

        int[] intArray = {
            123,
            456,
            789
        };

        try{
            System.out.println(intArray[3]);
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println("catch block");
            e.printStackTrace();//例外の表示
        }

        System.out.println("complete");
    }
}

コマンドライン
ws>javac -encoding UTF-8 Sample19_13.java
ws>java Sample19_13
catch block
java.lang.ArrayIndexOutOfBoundsException: 3
        at Sample19_13.main(Sample19_13.java:12)
complete


尚メッセージは、例外の種類とスローした場所を示しています。
この場合は、
  ArrayIndexOutOfBoundsExceptionが
  引数 3 によって
  Sample19_13クラスの
  mainメソッドでスローしました。
  (Sample19_13.javaファイルの 12行目です。)
という具合です。

具体的な情報が
表示されるのは助かるわ。


6. 例外時にメソッドを終了するサンプル


例外をキャッチしたらメソッドを終了したい場合は、catchロックの終わりに return を記述します。

強制終了させるのではなく、
穏便に終了したい場合はこれだな。
//Sample19_14.java
class Sample19_14{
    public static void main(String[] args){

        int[] intArray = {
            123,
            456,
            789
        };

        try{
            System.out.println(intArray[3]);
        }catch(ArrayIndexOutOfBoundsException e){
            e.printStackTrace();//例外の表示
            System.out.println("中断");
            return;//mainメソッド終了
        }

        System.out.println("complete"); //例外時には実行されない
    }
}

コマンドライン
ws>javac -encoding UTF-8 Sample19_14.java
ws>java Sample19_14
java.lang.ArrayIndexOutOfBoundsException: 3
        at Sample19_14.main(Sample19_14.java:12)
中断

return って
こんな風に使えるんすね~。


7.スローされる例外の名前の調べ方


この何とかエクセプション?てやつ
覚えなきゃいけないの?




私は覚えられないから
あえて例外をスローさせて
出てきたメッセージをコピペしてる。
コマンドライン
ws>javac -encoding UTF-8 Sample19_11.java
ws>java Sample19_11
>Exception in thread "main"
 java.lang.ArrayIndexOutOfBoundsException: 3   ←ココ
        at Sample19_11.main(Sample19_11.java:11)

java.lang は省略できます。


このメソッドは try-catch したよな~
ぐらいで大丈夫だと思う。
なるほど。
それなら綴りまでは覚えなくても
大丈夫そうですね。

例外の名前の調べ方
  例外の名前は綴りも長くて覚えにくいですね。
  例外処理を書かないで例外をスローさせると、
  必要な例外の名前が表示されます。
  これをコピペすると便利ですよ。
  try-catch してe.printStackTraceメソッドでもいいですね。



8.例外の名前がめんどくさい場合


あんまりおすすめしたくないんだけど。
何の例外でも
とりあえずキャッチするならこれで。
//Sample19_15.java
class Sample19_15{
    public static void main(String[] args){

        int[] intArray = {
            123,
            456,
            789
        };

        try{
            System.out.println(intArray[3]);
        }catch(Exception e){
            System.out.println("catch block");
            e.printStackTrace();//例外の表示
        }

        System.out.println("complete");
    }
}

コマンドライン
ws>javac -encoding UTF-8 Sample19_15.java
ws>java Sample19_15
catch block
java.lang.ArrayIndexOutOfBoundsException: 3
        at Sample19_15.main(Sample19_15.java:12)
complete


これでいいじゃん!


え~っ!


お疲れ様でした。


© 2019 awasekagami