Java – String – イミュータブル

概要

JavaのStringの挙動について整理してみた。

同一性と同値性

String型のオブジェクトの同一性と同値性(等価性)について、以下のコードで確認した。

  • s2s1の参照値を代入しているので、s1s2は同一であり同値
  • その後にs2の内容を変更すると、s1とは内容も参照値も異なるようになる
  • s3には別のリテラルでs1と同じ内容を代入しているが、s1s3は同一であり同値

すなわち同じ内容のStringリテラルを用いると、それらリテラルは1つのインスタンスとして共有される。

同値なオブジェクトと同一性

以下のコードで、同値なオブジェクトが常に同一になるか(共有されるか)確認した。

  • s5は2つのStringリテラルからs4と同じ値のリテラルを作り出していて、s4s5は同一であり同値
  • s6は内容が"ABC"の変数s1Stringリテラルからs4と同じ値のリテラルを作り出しているが、s4s6は同値ではあるが同一ではない

すなわち以下の様に整理される。

  • リテラルから生成された内容が同じ場合は1つのインスタンスとして共有される
  • 変数を含めた操作で生成されたインスタンスは、同じ内容のものがあっても別のインスタンスとして扱われる

Stringのイミュータビリティー

以下の様にStringはイミュータブルと言える。

  • 異なる内容のStringリテラルは異なるインスタンスとして生成され、参照される
  • Stringクラスで変更を伴うメソッドはStringを戻り値としており、インスタンスの内容を直接は変更できない
  • Stringクラスはfinal宣言されており継承はできない(クラスを継承して自身を変更することはない)

なおStringに関しては、同値であっても同一でない(インスタンスが異なる)場合がある。

  • リテラル同士の結合結果が他のリテラルに等しい場合、その内容は1つのインスタンスとして共有される(同一であり同値)
  • String変数を含む結合結果が他のリテラルに等しい場合でも、それらは別のインスタンスとして扱われる(同値だが同一ではない)

リテラルと変数での挙動の違いは、コンパイルレベルで値を同じかどうかを判断しているためか。

これらの場合があるとしても、一度設定されたオブジェクトの内容を変更することはできないため、String型はイミュータブルであると言える。

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です