12

Java 文字列がどのように不変であるかを正確に理解しようとしています。これはおそらく簡単な概念だと思いますが、いくつかのオンライン Web ページを読んでも、まだよくわかりません。

Java Strings が「不変」である理由がわかりません。現在、次のコードがあります。

public static void main(String[] args) {

  String name = "Jacob Perkins";

  System.out.println( name );

  name = name + "!";

  System.out.println( name );

}

私の出力は次のとおりです。

Jacob Perkins
Jacob Perkins!

文字列が不変であると想定されている場合、なぜこれが起こるのですか? 文字列に値を再割り当てできるのはなぜですか?

4

7 に答える 7

35

画像でこれを説明しましょう:

文字列の例

左側には変数がありますが、これは実際には参照です。

  1. String name = "Jacob Perkins;"文字列「Jacob Perkins」が作成され、それをname指します。
  2. name = name + "!";新弦「ヤコブ・パーキンス!」が作成され、参照は新しい文字列を指すようになりました。ただし、 String は不変であるため、古いものは変更されません。
于 2013-05-08T04:22:44.280 に答える
5

文字列自体は、一度作成すると変更できません。コード サンプルが行うことは、 nameの文字列を、nameの以前の内容と感嘆符から作成された新しい文字列に置き換えることです。(変数によって参照されなくなったnameの元の内容は、最終的にガベージ コレクターによって取得されます。)

コンパイルされたコードを調べる (またはデバッガーでステップ実行する) と、name + "!"式が StringBuilder オブジェクトの作成とそのオブジェクトに対するいくつかの操作にコンパイルされていることがわかります。

つまり、文字列は不変ですが、変数 はそうではありません。その値は、別の文字列を指すように変更されます。弦自体は決して変化しません。

于 2013-05-08T04:16:57.517 に答える
1

String オブジェクトは、変数参照が変更されるだけで不変です。

あなたの例では、「Jacob Perkins」オブジェクトがまだ存在し、新しいオブジェクト「Jacob Perkins!」が存在します。作成されます。

name 変数は新しいオブジェクトを指します。

于 2013-05-08T04:12:06.077 に答える
1

多分これはあなたが理解するのを助けるでしょう。

クラス Point (java.awt.Point) があるとします。1 つのインスタンス p があるとします。

Point p = new Point(0,0);

次に、同じオブジェクト p を参照する新しい変数 y を次のように作成します。

Point y = p;

p の値を変更すると、y も変更されます。クラス Point は可変であるためです。

p.setLocation(1,1);

y が場所 1,1 も参照するようにします。

String クラスを使用すると、それは起こりません。

String a = "123";
String b = a;

a = a + "4"; にすると、a の新しい値は「1234」になりますが、b は「123」のままです。

彼らが参照していたオブジェクトは変更されていません。単に a が別のオブジェクトを指しているだけです。

于 2013-05-08T04:28:49.713 に答える
0

実際には、3 つの String オブジェクトが作成されます。「ジェイコブ・パーキンス」、「!」と「ジェイコブ・パーキンス!」。「Jacob Perkins」インスタンスを実際に変更したわけではありません。名前変数の参照を「Jacob Perkins」インスタンスから「Jacob Perkins!」に変更しました。

于 2013-05-08T04:12:44.643 に答える
0
String name = "Jacob Perkins";

String name2 = name + "!";
name.substring(5); // or wather syntax is

それらは変数名を変更しません

于 2013-05-08T04:14:33.540 に答える
0

Java には参照があり、値があります。

あなたが言う時

String foo = "John Smith";

foo参照を保持する変数です。参照は、「John Smith」を含むオブジェクトまたは値を指しています。

変数が保持する参照は変更可能です。私がすることができます:

foo = "Jack Smith";

そして、参照を変更しました。ただし、次のようなコードを記述した場合:

String foo = "John Smith";
String bar = foo; //bar's reference is a copy of foo's reference - the same value
foo = "Jack Smith";
System.out.println(bar); //prints John Smith

foo を変更しても、bar は変更されていないことがわかります。なんで?簡単に言えば、私たちが書いたときに、foo = "Jack Smith";foo が新しい String を指すようにしました。Java の No メソッドは文字列を変更したり変更したりできるため、foo を使用して文字列を変更することはしませんでした。代わりに、新しい文字列が返され、変数は新しい不変の文字列を指すように作成されます。このように、文字列変数が「指す」オブジェクトは、その変数を介して以外は変更できません。これは Java 言語が保証する重要な特性です。

于 2013-05-08T04:23:41.700 に答える