最近、私が仕事を探していたとき、審査官は私に簡単な質問をしてくれました:「StringBufferとStringBuilderの違い、彼らのアプリケーションのシナリオは何ですか?」編集者の回答は以下で共有されているため、レコードを作成するために、誰もが将来学ぶことができます。
実際、Googleマスターを探してください。答えが得られます。StringBufferはStringBuilderのメソッドと機能と完全に同等ですが、StringBufferのほとんどのメソッドは、変更に同期されたキーワードを使用しているため、スレッドセーフです。この変更がなければ、StringBuilderはスレッドUnsafeと見なすことができます。
上記の答えをよりよく理解するために、StringBufferとStringBuilderのソースコードの実装がより現実的であることを直接確認することをお勧めします。プログラマーとして、「質問がある場合は、ソースコードを見てください」が正しい方法です。もちろん、責任を持って言うことができます、あなたは条件を持っている必要があります!
JDKの実装では、StringBufferとStringBuilderの両方がAbstractStringBuilderから継承されています。マルチスレッドのセキュリティと非安全性については、StringBufferの同期メソッドを大まかに理解することができます。
ここでは、AbstractStringBuilderの実装原則について簡単に説明します。StringBufferを使用することは、Javaの文字列接続の効率を改善することに過ぎないことを知っています。 AbstractStringBuilderは、char配列を使用して、追加する必要がある文字列を保存します。 Charアレイの初期サイズはあります。付録文字列の文字列の長さが現在のchar配列容量を超えると、charアレイは動的に拡張されます。つまり、より大きなメモリスペースを再適用してから、現在のchar配列を新しい場所にコピーします。メモリの再割り当てとコピーのオーバーヘッドは比較的大きいため、メモリスペースを再適用するたびに、メモリスペースが必要な電流よりも大きく、2倍になるようになります。
次に、楽しんでください!
Googleの情報は次のとおりです。
【
StringBufferはJDK 1.0で始まりました
StringBuilderはJDK 1.5で始まりました
JDK 1.5から始めて、文字列変数を使用した接続操作(+)はJVMによって内部的に使用されます
StringBuilderが実装され、この操作はStringBufferを使用して実装されました。
】
簡単なプログラムを通じて実行プロセスを見ていきます。
リスト1 buffer.java
public class Buffer {public static void main(string [] args){string s1 = "aaaaa";文字列s2 = "bbbbbbb";文字列r = null; int i = 3694; r = s1 + i + s2; for(int j = 0; i <10; j ++){r+= "23124"; }}}コマンドjavap -cバッファーを使用して、bytecodeの実装を表示します。
2つのバッファクラスバイトコードをリストします
対応するリスト1とリスト2、リスト2のLDC命令は、一定のプールからスタックの上部に「AAAA」文字列をロードし、ISTORE_1は変数1に「AAAAA」を保存します。以下は同じです。 Sipushは、短い整数定数値(-32768〜32767)をスタックの上部に押し込みます。これが一定の「3694」です。 Javaの指示セットについては、別の記事「Java命令セット」を確認してください。
13、13〜17がStringBufferオブジェクトの新しいものであり、初期化方法を呼び出すことを直接確認します。 20〜21は、最初に変数1をAload_1を介してスタックの上部に押します。前述のように、変数1が文字列定数「aaaaa」に入れられ、その後、「aaaaa」を一緒にスプライスするために、invokevirtual invokevirtualを介してstringbufferの追加方法を呼び出します。次の24〜30は同じです。最後に、33では、StringBufferのToString関数が呼び出され、文字列結果を取得し、ストアで変数3に保存されます。
これを見ると、「JVMはStringBufferを使用して文字列を接続するため、StringBufferを使用する必要はありません。「+"Just!」を使用する必要はありません。それは本当ですか?もちろん違います。 「存在には理由がある」ということわざにあるように、後続のループに対応するバイトコードを見てみましょう。
37〜42はすべて、ループを入力する前にいくつかの準備です。 37、38ここでjを1。44に設定します。if_icmpgeはjを10と比較します。Jが10を超える場合、73に直接ジャンプします。つまり、返品ステートメントは関数を終了します。それ以外の場合、ループ、つまり47〜66のバイトコードに入ります。ここでは、「+」操作を実行するたびにJVMが文字列接続を処理するために新しいstringbufferオブジェクトを実行するたびに、コードでstringbufferを使用して文字列接続を処理する理由を知るために47〜51を調べる必要があります。