Stringクラスのインスタンス

今回は、数値、配列、インスタンスの構造等について主に紹介してきましたが、「文字列」については一切言及しませんでした。ここでは文字列の内部構造について紹介します。

文字と文字列

Javaには「文字」というデータを表すためのcharという型が用意されています。これは文字列とは異なり、本当に1文字だけを表すためのものです。この「文字」は数値と同様に、変数に直接記憶させることができる(参照と実体に分かれない)データです。たとえば、次のように使えます。

void start() {
    char c = '1';
    JOptionPane.showMessageDialog(null, c);
}

文字列のリテラルは「"Hello"」のように二重引用符(")で全体を囲んでやりますが、文字のリテラルは「’A’」のように一重引用符(‘)で1文字を囲んでやります。’1’は文字の「1」を表すリテラルですので、上記のプログラムは「1」とだけ表示します。

一方で、Javaの文字列は、この「文字」を利用したクラスのインスタンスで構成されています。具体的には、java.langパッケージのStringというクラスがこれまで使っていたStringのクラスで、そのクラスのフィールドにはchar[] (文字の配列)型で文字列を構成する文字の並びを記憶させています。

図: Stringインスタンス

ただし、Stringクラスのインスタンスは高度 な技法によって「外側から変更できない」という特性を持っています(後続のコースで「情報隠蔽」や「不変オブジェクト(または不変クラス)」などが紹介されると思います)。このように、Stringはクラスのインスタンスでありながら変更できないため、今回のテキストでは紹介から外しています。

文字列の比較

このコースでは「文字列の比較」というものを説明せずに進めています。これは文字列が数値と異なり「クラスのインスタンス」であるという特性から、比較するための演算子である==や!=をそのまま使えないためです。例として、次のようなプログラムを作成して実行し、入力ダイアログに「こんにちは」と入力するとどうなるでしょうか。

String input = JOptionPane.showInputDialog("文字列を入力");
String answer = "こんにちは";
if (input == answer) {
    JOptionPane.showMessageDialog(null, "同じインスタンスです");
}
else {
    JOptionPane.showMessageDialog(null, "別のインスタンスです");
}

結果は「"別のインスタンスです"」と表示されます。==や!=という演算子は、文字列の「文字の並び」に関する比較を行うのではなく、「参照している実体が同じであるかどうか」という比較を行います。つまり、同じ文字の並びであっても、別の実体であれば上記のように別物として取り扱われてしまいます。

図: 参照の比較

もし内容を比較したい場合には、下記のように「a.equals(b)」という形式で書きます。

String input = JOptionPane.showInputDialog("文字列を入力");
String answer = "こんにちは";
if (input.equals(answer)) {
    JOptionPane.showMessageDialog(null, "同じ文字列です");
}
else {
    JOptionPane.showMessageDialog(null, "別の文字列です");
}

これはこのコースの範囲を超えた内容で、理解には「インスタンスメソッド」や「ポリモーフィズム」といったオブジェクト指向特有の知識が必要です。今のところは、「a.equals(b) と書くと文字列の内容を比較できる」程度にとどめておいてください。