String x = new String("xyz");
String y = "abc";
x = x + y;
String
このコードでいくつのオブジェクトが作成されるでしょうか?
少なくとも 4 つのオブジェクトがあります。
"xyz"
"xyz"
文字列のコピー"abc"
String x = new String("xyz");
1つあります:"xyz"
インターンされた文字列です。
次の 2 つがありますnew String("xyz")
。
String y = "abc";
3 つあります:"abc"
はインターンされた文字列です。
x = x + y;
4つあります。文字列は不変であるため、3 番目の文字列オブジェクトを作成する必要があります: new String("xyzabc")
.
コンパイラは StringBuilder を使用して文字列連結を実行できるため、5 番目のオブジェクトが存在する可能性があります。
StringBuilder s = new StringBuilder(x);
s.append(y);
x = s.toString();
クラスがロードされると、文字列リテラルごとに 1 つずつ、2 つの String オブジェクトが作成されます (ほとんどの場合)。これは一度限りのことです...
コードが実行されるたびに、2 つの文字列が作成されます。
は、状態がリテラルnew String("xyz")
と同じ新しい String を作成します。"xyz"
String 連結x + y
により、2 番目の新しい String が作成されます。
String y = "abc";
新しい文字列を作成しないことに注意してください。代わりに、既存の String への参照を に割り当てy
ます。実際、これは、クラスがロードされたときに作成されたリテラルの String オブジェクトへの参照です。
実際、ドリルダウンすると、char[]
作成された String オブジェクトごとに配列が作成されます。また、文字列の連結には、一時オブジェクトの作成が含まれる場合があります。StringBuilder
これらは両方とも実装の詳細です。
クラスをロードしても、新しい String オブジェクトが作成されない可能性もあります。文字列リテラルが文字列プール内の文字列オブジェクトによって表されることは事実ですが、それがどのように行われるかの正確なプロセスは実装の詳細です...そして、必ずしも新しく作成された文字列オブジェクトを呼び出す必要はありません。String.intern
さらに別の答えは、ゼロのオブジェクトが作成されるということです。それは単なる Java ソース コードであり、コンパイルして実行しない限り、Java ソース コードはオブジェクトを作成しません。(タダ!!)
x : クラス String の new キーワードとコンストラクターを使用しているため、String オブジェクトが作成されます。
"abc": は文字列リテラルであり、Java は文字列リテラルに遭遇するたびに String オブジェクトを作成します。
x : 2 つの文字列の連結は StringBuilder.append(X).append(Y).toString() に変換されるため、ここに別のオブジェクトが作成されます。