コンパイルしたコードをjavacコマンドラインで確認し、+演算子を使用して文字列連結を使用するたびに、コンパイルしたコードがStringBuilderのappend()メソッドに置き換えられていることを確認しました。StringBuilderとString連結を使用すると、バイトコードが類似しているため、パフォーマンスは同じだと思いますが、正しいですか?
2 に答える
ええ、それは本当です!ただし、ループで連結すると、動作が異なります。例えば
String str = "Some string";
for (int i = 0; i < 10; i++) {
str += i;
}
newStringBuilder
は、すべての単一ループ反復(strの初期値)で構築され、すべての反復の終わりに、初期String(実際にStringBuilder
は初期値str
)との連結が行われます。
したがって、文字列連結をループで操作する場合にのみ、自分でStringBuilderを作成する必要があります。
主な違い(およびコンパイラがStringBuilder
文字列の連結に使用する理由)String
は不変であるのに対し、StringBuilder
そうではないということです。
たとえば、s1 + s2 + s3
文字列のみを使用して計算するには、s1
の文字を2回コピーする必要があります。これは、を使用することで回避できます(回避できます)StringBuilder
。
この最適化は、JLSによって明示的に許可されています。
実装は、中間のStringオブジェクトの作成と破棄を回避するために、変換と連結を1つのステップで実行することを選択できます。繰り返される文字列連結のパフォーマンスを向上させるために、JavaコンパイラはStringBufferクラスまたは同様の手法を使用して、式の評価によって作成される中間Stringオブジェクトの数を減らすことができます。