« Setting JAVA_HOME on Mac OS X | Main | iCab 3.0.3 Beta 452 »

Fri, Jun 08, 2007

Java String Concatenation

Recently I found another blog posting about how Java concatenates strings. While the author is absolutely right that you should use java.util.StringBuffer or StringBuilder in loops, the very first example is not quite correct.

If you use a line like

String str = "foo" + "bar" + "Oh my, there must be a more efficient way...";
 

i.e. if you concatenate only String literals and constant expressions (and no variables) the Java compiler uses no StringBuffer/StringBuilder at all, but compiles the String values into a single string. Here's proof. Consider this simple class:

public class StringTest {
    public static final String STR = "ABC" + "DEF";

    public static void main(String[] args) {
        final String str = "abc" + "def";
        System.out.println( STR );
        System.out.println( str );
    }
}

Compile it into bytecode and disassemble it with javap -c StringTest:

public class StringTest extends java.lang.Object{
public static final java.lang.String STR;

public StringTest();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   3:   ldc     #3; //String ABCDEF
   5:   invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   8:   getstatic       #2; //Field java/lang/System.out:Ljava/io/PrintStream;
   11:  ldc     #5; //String abcdef
   13:  invokevirtual   #4; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   16:  return
}

As you can see, at runtime there's no String concatenation any more, but only pre-concatenated String constants (bold lines). So, it's definitely absolutely ok to break down long String values into smaller, concatenated chunks without any runtime performance penalty at all.

Posted by Thomas Much at 13:54
Edited on: Sun, Jun 17, 2007 15:09
Categories: Java