3

疑問に思っていることがいくつかあります。文字列はJavaでは不変であるため、たとえば既存の文字列オブジェクトに割り当てるときに、変更されるのではなく、新しい文字列オブジェクトが作成されることを知っています。

今私の質問に。次のコードがあるとします。

String a = "Hello World";
String b = "Hello World";

String res = a.substring(0,4) + b.substring(6,10);

3 行目のコードによって作成される文字列オブジェクトの数は? substring を呼び出すたびに、新しい文字列オブジェクトが作成されますか? 上記のコードは 3 つの新しい文字列オブジェクトを生成しますか?

前もって感謝します

4

2 に答える 2

8

Java の文字列は不変です。基本的にこれは、文字列オブジェクトを作成すると、文字列の内容を変更/変更できないことを意味します。その結果、文字列の内容を変更する「ように見える」文字列オブジェクトに対して何らかの操作を実行すると、Java は新しい文字列オブジェクトを作成し、新しく作成されたオブジェクトに対して操作を実行します。

これに基づいて、上記のコードは 5 つの文字列オブジェクトを作成するように見えます.2 つは宣言によって作成され、2 つは への呼び出しによって作成されsubstring、最後の 1 つは 2 つの部分を連結した後に作成されます。

ただし、不変性は別の興味深い結果につながります。JVM は、文字列リテラルを作成するための文字列プールのようなものを内部的に維持します。メモリを節約するために、JVM はこのプールの文字列オブジェクトを使用しようとします。新しい文字列リテラルを作成するたびに、JVM はプールにループして、既存の文字列を使用できるかどうかを確認します。存在する場合、JVM は単純にそれを使用して返します。

したがって、技術的には、Java 7 より前では、JVM はコード全体に対して 1 つの文字列オブジェクトのみを作成します。呼び出しでもsubstringプールに新しい文字列オブジェクトが作成されず、既存の「Hello World」オブジェクトが使用されますが、この場合、たとえば部分文字列への最初の呼び出しには位置 0 から 3 までの文字のみが使用されます。Java 7 以降、部分文字列は文字を共有しませんが、新しい文字を作成します。したがって、合計オブジェクト数は 4 になります。最後のオブジェクトは、2 つの部分文字列を連結して作成されます。

編集 コメントであなたの質問に答えるには、Java言語仕様を見てください-

Java プログラミング言語では、C とは異なり、char の配列は String ではなく、String も char の配列も '\u0000' (NUL 文字) で終了しません。

String オブジェクトは不変です。つまり、その内容は変更されませんが、char の配列には変更可能な要素があります。

クラス String のメソッド toCharArray は、String と同じ文字シーケンスを含む文字の配列を返します。クラス StringBuffer は、文字の変更可能な配列に便利なメソッドを実装します。

いいえ、Java では char 配列は不変ではなく、変更可能です。

于 2013-04-19T15:52:54.083 に答える
0

リテラル a は新しく作成され、プールに保持されます。リテラル b は a を参照し、代わりに新しいものを作成しません。

substring は新しい文字列を作成し、concatenate は毎回新しい文字列を作成するため、3 行目では 3 つの新しい文字列が作成されます。

文字列部分文字列(int beginIndex,int endIndex)

この文字列の部分文字列である新しい文字列を返します。部分文字列は、指定された beginIndex で始まり、インデックス endIndex - 1 の文字まで拡張されます。したがって、部分文字列の長さは endIndex-beginIndex になります。

于 2013-04-19T15:48:54.757 に答える