Wiki内検索
カウンタ
メニュー
最近更新したページ
最新コメント
トップページ by awesome things!
トップページ by check it out
Generics(Java) by stunning seo guys
String(Java) by awesome things!
トップページ by check it out
PHPのページ by stunning seo guys
Tomcatのページ by stunning seo guys
トップページ by check it out
トップページ by awesome things!
タグ

例外(Java)

例外


はじめに

ここでは、例外(Exception)処理について説明します。

例外とtry〜catch

Javaの実行時エラーには、エラー(Error)と例外(Exception)があり、前者はプログラムの停止に至る「致命的なエラー」、後者は実行時例外(プログラムの実行時に発生するエラー)などの対処可能なエラーを意味します。たとえば、よくある「配列あふれ」の場合には、java.lang.ArrayIndexOutOfBoundsExceptionという例外が発生します。

ためしに配列をあふれさせてみましょう。Sample018を作ってみましょう。

package test.basic;

public class Sample018 {

    // int型の3の要素をもつ配列の宣言
    static int[] i1 = new int[3];

    public static void main(String[] args) {

        for(int i=0;i<10;i++){
            arrayAdd(i,i);
            System.out.println(Integer.toString(i));
        }

    }

    private static void arrayAdd(int i, int value){
        i1[i]=value;
    }
}

このプログラムは「3つしか用意していない配列に10個の要素をいれる」という全く間違ったものですね。ためしに実行してみてください。以下のようなメッセージがコンソールにでましたでしょうか?

0
1
2
java.lang.ArrayIndexOutOfBoundsException: 3
    at test.basic.Sample018.arrayAdd(Sample018.java:24)
    at test.basic.Sample018.main(Sample018.java:17)
Exception in thread “main”


標準出力には、期待通り4回目のルーチンで実行エラーが起こっていることが示されています。また、「at」から始まるメッセージは「スタックトレース」といいエラーの発生箇所から呼び出し元をたどる情報を提供します。(エラーが発生した行番号まで表示されます)

こういったエラーの恐れはいろいろなところに潜みますから、あらかじめ「でる恐れのあるところ」は予防線をはってエラー時の適切な処理を実装しておきたいですよね。

その方法論に行く前にもうひとつサンプルを実行してみましょう。Sample019を作ってみましょう。

package test.basic;

public class Sample019 {

    public static void main(String[] args) {

        throwEx();

    }

    private static void throwEx() throws NullPointerException{
        NullPointerException npe = new NullPointerException();
        throw npe;
    }
}


この例では、throwEx()メソッドでNullPointerException(Null値を触ったときによく出るException)をインスタンス化しています。また、例外というのは「投げる」というのが正しい「動詞」のようで、

        throw npe;

で呼び出し元に例外を「投げつけて」います。このようにExceptionも(特殊な役割を持っているとはいえ)クラスですので、プログラマが自作したり、また、故意にthrowすることが可能です。また、メソッドの宣言部に「throws NullPointerException」という句がありますが、これは、「このメソッドはNullPointerExceptionをなげるぜ」という宣言です。

さきほど、例外を「呼び出し元に投げつける」と書きましたが、投げつけられた方でも「なんらかのエラー処理をする」という選択と、「自分の呼び出し元に投げつける」という選択があります。以下では、この「なんらかのエラー処理をする」方法について、簡単に説明します。

このように例外が発生しそうな箇所(もしくは、発生させる箇所)で、Exceptionを補足するには、「try〜catch〜finally」句を仕掛けておきます。この構文は以下です。

try{
    例外が発生するかもしれない処理
}catch(補足する例外クラス名1 変数名1){
    クラス名1の例外が発生したときのエラー処理
}catch(補足する例外クラス名2 変数名2){
    クラス名2の例外が発生したときのエラー処理
}finally{
    例外の発生に関わらずかならず実行する処理。
}

それでは、まず、Sample018を修正してみましょう。Sample018をSample018_1という名前でコピーして、以下のように修正してください。

package test.basic;

public class Sample018_1 {

    // int型の3の要素をもつ配列の宣言
    static int[] i1 = new int[3];

    public static void main(String[] args) {

        for(int i=0;i<10;i++){
            arrayAdd(i,i);
            System.out.println(Integer.toString(i));
        }

    }

    private static void arrayAdd(int i, int value){
        try{
            i1[i]=value;
        }catch(ArrayIndexOutOfBoundsException e){
            System.out.println("配列があふれました。indexは"+Integer.toString(i));
        }finally{
            System.out.println("ここはfinally句です。");
        }
    }
}


arrayAdd()メソッドで配列あふれが発生していますので、このなかで例外の処理をしています。それではこれを実行してみてください。以下のような出力がでて、プログラムが止まることなく実行されていることが分かります(finally句をかならずとおっていることも分かりますね)。

ここはfinally句です。
0
ここはfinally句です。
1
ここはfinally句です。
2
配列があふれました。indexは3
ここはfinally句です。
3
配列があふれました。indexは4
ここはfinally句です。
4
配列があふれました。indexは5
ここはfinally句です。
5
配列があふれました。indexは6
ここはfinally句です。
6
配列があふれました。indexは7
ここはfinally句です。
7
配列があふれました。indexは8
ここはfinally句です。
8
配列があふれました。indexは9
ここはfinally句です。
9

次に、Sample019を修正してみましょう。Sample019をSample019_1という名前でコピーして、以下に修正してください。

package test.basic;

public class Sample019_1 {

    public static void main(String[] args) {

        try{
            throwEx();
        }catch(NullPointerException e){
            System.out.println("NullPointerExceptionが発生しました。");
        }finally{
            System.out.println("ここはfinally句です。");
        }

    }

    private static void throwEx() throws NullPointerException{
        NullPointerException npe = new NullPointerException();
        throw npe;
    }
}




この例では、throwEx()メソッドは(その呼び出し元のmainメソッドへ)例外を放り投げることを決めているので、mainメソッドを修正しています。これを実行してみてください。プログラムは終了して、以下のようなメッセージがでましたか?


NullPointerExceptionが発生しました。
ここはfinally句です。


これで例外についての説明はとりあえず終わりです。

「例外を積極的に使うべきか否か」というのは議論が分かれるところで、極端な場合には(非常に軽微なエラーであっても)例外を発生させて上位プログラムに知らせるとかいうコーディングもありえます(エラーメッセージの代わりに使うようなイメージですね)。ですが、Exceptionを発生させることはコストの高い(負荷の高い)処理と言えます。例外をthrowすべきかどうかは、それが本当にベストな選択かどうか考えてきめるべき、というのが一般論です。
2007年02月26日(月) 15:35:21 Modified by wanderingse




スマートフォン版で見る