String s = "hello";
String backup_of_s = s;
s = "bye";
この時点で、バックアップ変数には元の値「hello」が含まれています(これはStringの不変性のためですか?)。文字列をJavaでどのようにコピーすればよいですか?
しかし、実際に安全なこのメソッドで文字列をコピーすることはできますか(これはもちろん、通常の変更可能なオブジェクトをコピーすることは安全ではありません)、またはこれを書く方が良いですか? :
String s = "hello";
String backup_of_s = new String(s);
s = "bye";
つまり、これらの2つのスニペットの違いは何ですか?
EDIT - 最初のスニペットが安全である理由:
は私がちょうどもう少し詳細に物事を説明させて、すでに提供良い回答に基づいて(本質的問題に焦点を当てました2つのスニペット間のパフォーマンスの差異):
文字列はJavaでは不変です。つまり、Stringオブジェクトは構築後に変更できません。したがって 、
String s = "hello";
は、新しい文字列インスタンスを作成し、s
String backup_of_s = s;
新しい変数backup_of_s
を生成し、それが現在のオブジェクトを参照するように初期化する(s
インスタンス/オブジェクトへの参照である)にそのアドレスを割り当てますs
によって参照される。
注:文字列の不変性は、このオブジェクトが変更されないことが保証されます:私たちのバックアップが安全である
注2:このオブジェクトは、限り、それは少なくとも一つによって参照されるように破壊されないことをJavaのガベージコレクションメカニズム保証(この場合はbackup_of_s
)変数
最後に、s = "bye";
は、(不変の、それが唯一の方法だから)、別の文字列のインスタンスを作成し、それが今、新しいオブジェクトを参照するようs
変数を変更します。
不変性はそれとは関係ありません。これは単にオブジェクト参照がどのように機能するかです。同等のStringBuilderの例を提供することができます。 – GriffeyDog
@BalusC、私は新しいString()がJVMのStringプール内に何かを作成することができないのか分かりません。文字列リテラルとintern()経由でプールにコミットされたリテラルのみがプール内にあります。 – Snicolas
@GriffeyDog:質問を文字通り読みにくいです。私が言っていることは、誰かが文字列を変更する恐れなしに、文字列オブジェクトへの参照を与えることは安全であるということです。 – NPE