![](/img/trans.png)
[英]Why to use StringBuffer in Java instead of the string concatenation operator
[英]String concatenation with operator + vs using stringbuffer?
如果我做實例方法,在連接方面是否存在b / w 1和2的差異。 我的意思是在任何一種情況下,最終只會構造一個對象,即“abc”。只是我看到的區別是測試將位於permgen空間內,即使線程來自實例方法,但是一旦線程超出方法,x將被垃圾收集但是構造的對象數量的術語將是相同的。 對?
// option 1
String test="a"+"b"+"c";
// option 2
StringBuffer x = new StringBuffer().append("a").append("b").append("c").toString()
我引用鏈接http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html來得出這個結論。
首先請注意,您鏈接的文檔非常陳舊。 請注意它適用於Java 1.4.2 。
J2SE 1.4.2處於Java Technology End of Life(EOL)過渡期。 EOL過渡期從2006年12月11日開始,將於2008年10月30日完成,屆時J2SE 1.4.2將達到其使用壽命終止(EOSL)。
在較新版本的文檔中,此語句已被刪除。 但是,您還應該注意另一個聲明:
從JDK 5發行版開始,這個類已經補充了一個等效類,專門用於單個線程StringBuilder。 StringBuilder類通常應優先於此使用 ,因為它支持所有相同的操作,但速度更快,因為它不執行同步。
其次請注意,您引用的文檔具有以下代碼:
x = "a" + 4 + "c";
4
這不僅僅是一個錯字。 您的示例不同,因為編譯器會將代碼轉換為僅使用單個字符串文字。 這兩行是相同的:
x = "a" + "b" + "c";
x = "abc";
字符串文字將被實習。
但是在編譯器不能只使用單個字符串文字的一般情況下,編譯器會將第一個版本轉換為第二個版本,但它會使用StringBuilder
因為它更有效。
首先, -使用StringBuilder
,而不是StringBuffer
, StringBuffer
現在已經過時。
對於你的問題,現在它並不重要,編譯器自動將String concacenation轉換為StringBuilder。
只有兩種情況可以使用它。 第一個是更好的代碼可讀性(例如,如果您正在構建像SQL查詢一樣的長字符串)。 第二個,當你在循環中使用Strings時,編譯器總是為每個遍歷循環創建一個新的StringBuilder實例,所以要小心。
首先, StringBuilder
是StringBuffer
ArrayList
是Vector
:它應該是首選的,因為它不是同步的。
您的第一個String完全在編譯時構造,並存儲為String文字。 此文字嵌入池中, test
變量始終指向同一個String實例。
您的第二個代碼段在運行時動態連接三個字符串文字。 每次調用它時都會返回一個新的String實例。
查看2個示例生成的字節碼,第一個字符串轉換為“abc”字符串文字,而第二個字符串調用StringBuilder方法。 您可以使用System.out.println(test == "abc");
實際測試它System.out.println(test == "abc");
,打印真實。
0: ldc #2 // String abc
2: astore_1
3: new #3 // class java/lang/StringBuffer
6: dup
7: invokespecial #4 // Method java/lang/StringBuffer."<init>":()V
10: ldc #5 // String a
12: invokevirtual #6 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
15: ldc #7 // String b
17: invokevirtual #6 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
20: ldc #8 // String c
22: invokevirtual #6 // Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
25: invokevirtual #9 // Method java/lang/StringBuffer.toString:()Ljava/lang/String;
28: astore_2
在這種特殊情況下,您在編譯時連接三個字符串文字,編譯器將生成代碼,就像您鍵入的一樣:
String test="abc";
從而完全避免任何中間物體。
我認為在內存使用情況下兩者都是相同的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.