Previous | Next | Trail Map | Writing Java Programs | String と StringBuffer クラス


最上位オブジェクトの Java の文字列

規約により、 C 言語と C++ の文字列は null で終わる文字の配列である。C 言語と C++ には文字列という本当の実体がない。 Java の文字列は最上位オブジェクトである。

オブジェクトとしての文字列は、プログラマにいくつかの利点を提供する。


これが Java 言語の重要な機能である理由を示すために、簡単な例をあげる。 次の C 言語の関数では、 str2 str1 の内容をコピーする。

int myStrCopy(char *str1, char *str2)
{
    for ( ; *str1 != '¥0'; str1++, str2++)
        *str2 = *str1;
}

予測不可能な C 言語の文字列の動作

上記の例で、開発者はコピーしながら両方の文字列を通して進むために、ポインタ演算を使用する。 プログラマが、ポインタを通して任意のメモリ位置を検査することができるのは強力なツールであるが、この能力は多くのエラーを引き起こす原因になりえる。 多くのエラーの原因は配列の最後から迷い出たポインタである。 上記の myStrCopy 関数には次のようなエラーがある。関数の for ループ は str2 の長さを検査しない。そしてもし str1 str2 より長いならば、文字列コピーは str2 の終わりからはみでて書き込む。 下記にそのバグを動かすプログラムがある。

main() {
    char *s = "HotJava is Cool!";
    char t[] = "Java is Cool!";

    printf("%s, %s¥n", s, t);
    myStrCopy(s, t);
    printf("%s, %s¥n", s, t);
}

私のマシンでは、プログラムは次のように出力する。

HotJava is Cool!, HotJava is Cool!%s, %s

myStrCopy str2 の終わりをはみ出て書き込み、それによってその後にメモリに格納されたものは何でも破壊される。注釈:  % s 、 % s はたまたま str2 の後にメモリロケーションに格納された文字であり、プログラムを各ユーザのマシンで実行する時は恐らく異なる。

もちろん、 myStrCopy のエラーは簡単に修正することができる。 しかしこのようなエラーは見つけることが難しい。

予測可能な Java の文字列

Java の文字列は、 String クラスあるいは StringBuffer クラスのいずれかから派生した最上位オブジェクトである。 これにより、共通クラス全体を見つけて修正したり、上記の例で示した些細なプログラムエラーを抹消する。

上記のプログラム(エラーを含む)を Java 言語で書き換える。

class strcpy {
    public static void main(String args[]) {
        String s = "HotJava is Cool!";
        StringBuffer t = new StringBuffer("Java is Cool!"
);

        System.out.println(s + ", " + t);
        myStrCopy(s, t);
        System.out.println(s + ", " + t);
    }

    static void myStrCopy(String str1, StringBuffer str2) {
        int i, len = str1.length();

        for (i = 0; i &lt len; i++)
            str2.setCharAt(i, str1.charAt(i));
    }
}

この置き換えでは、String クラス、 StringBuffer クラスを使用し、文字配列とポインタの代わりに指定された文字を得るためにメソッドが割り当てられていることに注意する。

C 言語バージョンのように、 myStrCopy メソッドの Java 言語バージョンは str1 の長さでループし、決して str2 の長さは確認しない。 したがって、 str1 str2 より長い時は、メソッドは str2 の最後を越えて文字を得ようとする。 しかし、 Java 言語バージョンを実行すると、次の実行時エラーメッセージを見ることができるであろう。

Exception in thread "main" java.lang.StringIndexOutOfRangeException String index out of range: 13
    at java.lang.Exception.&lt init &gt(Exception.java)
    at java.lang.StringIndexOutOfRangeException.&lt init &gt(StringIndexOutOfRangeException.java)
    at java.lang.StringBuffer.setCharAt(StringBuffer.java)
    at strcpy.myStrCopy(strcpy.java:23)
    at strcpy.main(strcpy.java:15)

C 言語のバージョンと Java 言語バージョンの主な違いは、 Cプログラムが予想不可能な動作をするのに対して、Java プログラムは信頼できる、明らかな障害を発生させることである。

Previous | Next | Trail Map | Writing Java Programs | String と StringBuffer クラス