简体   繁体   中英

String concatenation with operator + vs using stringbuffer?

Is there any difference b/w 1 and 2 in terms of concatenation if i do it instance method. I mean in either case only one object will be constructed ultimately ie "abc" .Yes only difference i see is test will lie inside permgen space even thread come out of instance method but x will be garbage collected once thread is out of method but in terms of number of objects constructred will be same. Right?

// option 1
String test="a"+"b"+"c";

// option 2  
StringBuffer x = new StringBuffer().append("a").append("b").append("c").toString()

I referred the link http://docs.oracle.com/javase/7/docs/api/java/lang/StringBuffer.html to reach this conclusion.

First notice that the documentation you have linked is very old. Notice it's for Java 1.4.2 .

J2SE 1.4.2 is in its Java Technology End of Life (EOL) transition period. The EOL transition period began Dec, 11 2006 and will complete October 30th, 2008, when J2SE 1.4.2 will have reached its End of Service Life (EOSL).

In newer versions of the documentation this statement has been removed. However another statement has been added that you should be aware of:

As of release JDK 5, this class has been supplemented with an equivalent class designed for use by a single thread, StringBuilder. The StringBuilder class should generally be used in preference to this one , as it supports all of the same operations but it is faster, as it performs no synchronization.


Secondly notice that the documentation you refer to has this code:

x = "a" + 4 + "c";

The 4 there isn't just a typo. Your example is different because the compiler will convert the code to use just a single string literal. These two lines are the same:

x = "a" + "b" + "c"; 
x = "abc";

The string literal will be interned.


But in the general case where the compiler cannot just use a single string literal, the compiler will transform the first version into the second, except it will use StringBuilder instead because it is more efficient.

First of all - use StringBuilder instead of StringBuffer , StringBuffer is deprecated now.

And for your question, nowadays it doesn't really matter, compiler automacally transforms String concacenation to StringBuilder.

There are only two cases where to use it. First one is better code readability (for example if you are building long Strings like SQL queries). And second one, when you concanete Strings in the loop, compiler for always make a new StringBuilder instance for each walk through loop, so be carefull about that.

First of all, StringBuilder is to StringBuffer what ArrayList is to Vector : it should be preferred because it's not synchronized.

Your first String is entirely constructed at compilation time, and is stored as a String literal. This literal is interned inside a pool, and the test variable always points to the same String instance.

Your second snippet dynamically concatenates, at runtime, three String literals. It returns a new String instance each time it's called.

Looking at the bytecode generated by the 2 examples, the first string is transformed into the "abc" string literal, whereas the second calls StringBuilder methods. You can actually test it with System.out.println(test == "abc"); , which prints true.

   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      

In this specific case, where you're concatenating three string literals at compile time, the compiler will generate code just as if you'd typed:

String test="abc";

thus avoiding any intermediate objects altogether.

我认为在内存使用情况下两者都是相同的。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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