StringとStringBuilderについての質問とまとめ
5059 ワード
テーマを见て本文が何を言うか知っています~先にコードをつけます!!
上記のコードは明らかで、それぞれテストします:String接続はどれだけのオブジェクトを生成しますか?SringBuilder接続はどのくらいのオブジェクトを生成しますか?1つの式で文字列を接続すると、どのくらいのオブジェクトが生成されますか?
次に、クラスのバイトコードファイルを示します.の
まず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滴???
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滴???