StringとStringBuilderについての質問とまとめ


テーマを见て本文が何を言うか知っています~先にコードをつけます!!
public class StringAndStringBuilderTest {
    
    @Test
    public void testString() {
        String str = "";
        for(int i = 0; i < 100; i++) {
            str += String.valueOf(i);
        }
    }

    @Test
    public void testStringBuilder() {
        StringBuilder sb = new StringBuilder("");
        for(int i = 0; i < 100; i++) {
            sb.append(String.valueOf(i));
        }
    }

    @Test
    public void testString() {
        String str = "a" + "b" + "c";
    }
}

上記のコードは明らかで、それぞれテストします:String接続はどれだけのオブジェクトを生成しますか?SringBuilder接続はどのくらいのオブジェクトを生成しますか?1つの式で文字列を接続すると、どのくらいのオブジェクトが生成されますか?
次に、クラスのバイトコードファイルを示します.の
public class StringAndStringBuilder {
  public StringAndStringBuilder();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public void testString();
    Code:
       0: ldc           #2                  // String 
       2: astore_1      
       3: iconst_0      
       4: istore_2      
       5: iload_2       
       6: bipush        100
       8: if_icmpge     39
      11: new           #3                  // class java/lang/StringBuilder
      14: dup           
      15: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
      18: aload_1       
      19: invokevirtual #5                  // Method java/lang/StringBuilder.append:
                                                (Ljava/lang/String;)Ljava/lang/StringBuilder;
      22: iload_2       
      23: invokestatic  #6                  // Method java/lang/String.valueOf:
                                                (I)Ljava/lang/String;
                                            // String , StringBuilder 
      26: invokevirtual #5                  // Method java/lang/StringBuilder.append:
                                                (Ljava/lang/String;)Ljava/lang/StringBuilder;
      29: invokevirtual #7                  // Method java/lang/StringBuilder.toString:
                                                ()Ljava/lang/String;
      32: astore_1      
      33: iinc          2, 1
      36: goto          5                    // for , 5 
      39: return        

  public void testStringBuilder();
    Code:
       0: new           #3                  // class java/lang/StringBuilder
       3: dup           
       4: ldc           #2                  // String 
       6: invokespecial #8                  // Method java/lang/StringBuilder."<init>":
                                                (Ljava/lang/String;)V
       9: astore_1      
      10: bipush        100
      12: istore_2      
      13: iload_2       
      14: sipush        200
      17: if_icmpge     35
      20: aload_1       
      21: iload_2       
      22: invokestatic  #6                  // Method java/lang/String.valueOf:
                                                (I)Ljava/lang/String;
                                            //append , String 
      25: invokevirtual #5                  // Method java/lang/StringBuilder.append:
                                                (Ljava/lang/String;)Ljava/lang/StringBuilder;
      28: pop           
      29: iinc          2, 1
      32: goto          13                    // , , 13 
      35: return        

  public void testString02();
    Code:
       0: ldc           #9                  // String abc
                                            // ~~
       2: astore_1      
       3: return        
}

まずtestStringメソッドのバイトコードを見てみましょう.
iload_から2からgotoまで、完全な循環体です.最初のJavaコードを見てください
バイトコードの11~32行目で、コンパイラはString接続をStringBuilderに自動的に変換し、キャッシュプールに押し込みます.元のStringは、StringBuilderのtoStringメソッドが返すStringオブジェクトを参照します.
29行目に表示され、最後にtoStringが呼び出され、オブジェクトが返されます.32行目には、元のSrting参照strがスタックからポップアップされていることがわかります.
したがって、Stringで文字列を直接接続すると、Stringの元の参照を1回使用するたびにStringBuilderオブジェクトが生成されます.
以上のように、キャッシュプールが空でない場合、または元のStringがnullでない場合、少なくとも2つのオブジェクト、1つのString、1つのStringBuilderが生成される.StringBuilderの後に追加するStringが定数プールと存在しない場合、最大2 N+1個のオブジェクトが発生する.
testStringBuilderメソッドのバイトコードを見ています.
13~32行目は、まだ完全なループです.Javaコードを参照してください.
バイトコードを見ると、testStringの方法とは明らかに違います.はっきりしている.
体内を循環する、StringBuilderオブジェクトの発生はなく、Stringのみである.valueOf()メソッドで生成された、StringBuilderのStringオブジェクトに追加します.
サイクルごとにStringBuilderオブジェクトの生成が少なくなるのは明らかです.
以上のように、キャッシュプールが空でない場合、少なくとも2つのオブジェクトが生成される.キャッシュプールに文字列を追加し続けると、新しい文字列が定数プールに存在しない場合、最大N+1オブジェクトが生成されます.
testSting()は2 N+1個のオブジェクトを生成し、testStringBuilder()はN+1個のオブジェクトを生成する.これはStringよりStringBuilder接続文字列が効率的であるためである.
StringBufferは同じです.
最後の方法testString 02()を見てみましょう...
String str = "a"+ "b"+ "c";
本当に1つのオブジェクトしか生まれませんか?バイトコードは、文字列定数プールから参照がポップアップされることを示すだけで、JVM解析CONSTANT_は説明されていません.Stringの場合、どのくらいのStringオブジェクトが生成されますか.
だから、最後に提出した質問に答えてください.jvmはどのようにCONSTANTを解析しますString滴???