Javaで文字列をコピーするにはどうすればよいですか?


198
    String s = "hello";
    String backup_of_s = s;
    s = "bye";

この時点では、バックアップ変数にはまだ元の値「hello」が含まれています(これは、Stringの不変性が原因ですか?)。

しかし、このメソッドを使用して文字列をコピーするのは本当に安全ですか(もちろん、通常の可変オブジェクトをコピーするのは安全ではありません)、またはこれを書く方が良いですか?:

    String s = "hello";
    String backup_of_s = new String(s);
    s = "bye";

言い換えれば、これらの2つのスニペットの違い(ある場合)は何ですか?


編集-最初のスニペットが安全である理由:

すでに提供されている適切な回答(基本的には2つのスニペット間のパフォーマンスの違いの問題に焦点が当てられていました)に基づいて、もう少し詳しく説明します。

文字列はJavaでは不変です。つまり、文字列オブジェクトは作成後に変更できません。したがって、

String s = "hello";新しいStringインスタンスを作成し、そのアドレスをssインスタンス/オブジェクトへの参照として)割り当てます

String backup_of_s = s;新しい変数backup_of_sを作成し、初期化して、現在参照されているオブジェクトを参照するようにしますsます。

注:文字列の不変性は、このオブジェクトが変更されないことを保証します。バックアップは安全です

注2:Javaガベージコレクションメカニズムは、このオブジェクトが少なくとも1つの変数(backup_of_sこの場合)

最後に、s = "bye";別のStringインスタンスを作成し(不変性のため、これが唯一の方法です)、s新しいオブジェクトを参照するように変数を変更します。

回答:


139

文字列は不変なので、どちらのバージョンも安全です。ただし、後者は効率が低下します(追加のオブジェクトが作成され、場合によっては文字データがコピーされます)。

これを念頭に置いて、最初のバージョンを優先する必要があります。


15
不変性はそれとは何の関係もありません。それは単にオブジェクト参照が機能する方法です。同等のStringBuilderの例を提供できます。
GriffeyDog、2012年

1
@ BalusC、new String()がJVMの文字列プールに何かを作成する方法がわかりません。文字列リテラルと、intern()を介してプールにコミットされたリテラルのみがプールにあります。
スニコラ2012年

3
@GriffeyDog:文字通りに質問を読んでいます。私が言っているのは、誰かが文字列を変更するのではないかと心配することなく、文字列オブジェクトへの参照を与えることは安全だということです。
NPE

2
@GriffeyDog私はあなたのコメントを非常に誤解を招くと思います:不変性は最初のスニペットを安全にするものです。
セバスチャン2014年

5
@Sebastien実行しているのはs、別のオブジェクト(String「さようなら」)を参照するように参照変数を再割り当てすることだけです。これは、参照変数backup_of_sが参照しているもの(String「hello」)には影響しません。言ったように、不変StringBuilderはない sを使用して同等の例を提供できます。私のコメントは主にOPsステートメントに関するものです。この時点では、バックアップ変数にはまだ元の値 "hello"が含まれています(これはStringの不変性が正しいためですか?)。
GriffeyDog 2014年

22

文字列は不変オブジェクトですので、参照されているオブジェクトは変更できないため、への参照をコピーするだけでコピーできます...

したがって、最初の例のように問題なくコピーできます。

String s = "hello";
String backup_of_s = s;
s = "bye";

10

2番目のバージョンは、単に行う必要がないときに余分な文字列オブジェクトを作成するため、効率が低下します。

不変性とは、最初のバージョンが期待どおりに動作することを意味するため、推奨されるアプローチです。


0

2番目のケースも文字列プールの点で非効率的です。戻り参照でインターンを明示的に呼び出してインターンにする必要があります。


-16
String str1="this is a string";
String str2=str1.clone();

このようなコピーはどうですか?新しいコピーを取得する方が良いと思います。そのため、データが参照され、さらにアクションで変更されてstr1も影響を受けませんstr2


3
String不変です。文字列のクローンはあまり意味がありません。
ウラジミール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.