繁体   English   中英

使用operator + vs使用stringbuffer进行字符串连接?

[英]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 ,而不是StringBufferStringBuffer现在已经过时。

对于你的问题,现在它并不重要,编译器自动将String concacenation转换为StringBuilder。

只有两种情况可以使用它。 第一个是更好的代码可读性(例如,如果您正在构建像SQL查询一样的长字符串)。 第二个,当你在循环中使用Strings时,编译器总是为每个遍历循环创建一个新的StringBuilder实例,所以要小心。

首先, StringBuilderStringBuffer ArrayListVector :它应该是首选的,因为它不是同步的。

您的第一个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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM