文字列の連結をデバッグするときにStringBuilderがポップアップするのはなぜですか?
文字列の連結(「+」演算子を使用)は通常、StringBuffer
またはStringBuilder
を使用して連結を行うコードにコンパイルされるためです。JLSは、この動作を明示的に許可します。
「実装は、中間のStringオブジェクトの作成と破棄を回避するために、変換と連結を1つのステップで実行することを選択できます。繰り返される文字列連結のパフォーマンスを向上させるために、JavaコンパイラはStringBufferクラスまたは同様の手法を使用して式の評価によって作成される中間文字列オブジェクト。」 JLS15.18.1。
(コードがではStringBuffer
なくを使用しているStringBuilder
場合は、おそらく、非常に古いJavaコンパイラを使用してコンパイルされたか、非常に古いターゲットJVMを指定したためです。StringBuilder
クラスはJavaに比較的追加されています。古いバージョンのJLS IIRCStringBuffer
の代わりに言及するために使用されます。)StringBuilder
また、JVM固有のものとそうでないものを指摘できるかもしれません。
生成されるバイトコードは"string" + variable"
、Javaコンパイラが連結を処理する方法によって異なります。(実際、生成されるすべてのバイトコードはある程度Javaコンパイラに依存します。JLSおよびJVMの仕様では、生成する必要のあるバイトコードは規定されていません。仕様では、プログラムの動作と個々のバイトコードの動作について詳しく説明しています。)
@supercatコメント:
文字列の連結で、たとえば2つのStringオブジェクトを受け入れ、適切な結合サイズのバッファを割り当ててそれらを結合するStringコンストラクタのオーバーロードが使用されないのはなぜでしょうか。または、より多くの文字列を結合する場合、String []を取るオーバーロード?結合する文字列への参照を含むString[]を作成することは、StringBuilderを作成することよりも費用がかからないはずです。また、完璧なサイズのバッキングストアを一度に作成できることは、パフォーマンスを簡単に向上させるはずです。
多分...しかし、私はおそらくそうではないと思います。これは、複雑なトレードオフを伴う複雑な領域です。文字列連結に選択された実装戦略は、さまざまなユースケースでうまく機能する必要があります。
私の理解では、元の戦略は、いくつかのアプローチを検討し、大規模な静的コード分析とベンチマークを実行して、どのアプローチが最適かを判断した後に選択されました。彼らはあなたが提案したすべての選択肢を検討したと思います。(結局のところ、彼らは/賢い人々でした...)
そうは言っても、Java 6、7、および8の完全なソースコードベースを利用できます。それはあなたがそれをダウンロードして、あなたの理論が正しいかどうか確かめるためにあなた自身のいくつかの実験を試みることができることを意味します。それらが...であり、それらが...であるという確かな証拠を収集できる場合は、OpenJDKチームにパッチを送信してください。