![](/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.