Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What happens at compile and runtime when concatenating an empty string in Java?

This is a question that arose mostly of pure curiosity (and killing some time). I'm asking specifically about Java for the sake of concreteness.

What happens, in memory, if I concatenate a string (any string) with an empty string, e.g.:

String s = "any old string";
s += "";

I know that afterward, the contents of s will still be "any old string", since an empty ASCII string is stored in memory as just an ASCII null (since, at least in Java, strings are always null-terminated). But I am curious to know if Java (the compiler? the VM?) performs enough optimization to know that s will be unchanged, and it can just completely omit that instruction in the bytecode, or if something different happens at compile and run times.

like image 210
Matt Ball Avatar asked Jul 27 '09 19:07

Matt Ball


People also ask

Can we concat empty string Java?

concat() Method. The String. concat() method is a good choice when we want to concatenate String objects. The empty String returned by the getNonNullString() method gets concatenated to the result, thus ignoring the null objects.

Can you concatenate an empty string?

Concatenating with an Empty String VariableYou can use the concat() method with an empty string variable to concatenate primitive string values. By declaring a variable called totn_string as an empty string or '', you can invoke the String concat() method to concatenate primitive string values together.

What is the purpose of an empty string in Java?

What is an “empty” String in Java? “An empty String in Java means a String with length equal to zero.” If a String is empty that means the reference variable is referring to a memory location holding a String of length equal to zero.

How does empty string work?

An empty string is a string instance of zero length, whereas a null string has no value at all. An empty string is represented as "" . It is a character sequence of zero characters.


2 Answers

It's bytecode time!

class EmptyString {
    public static void main(String[] args) {
        String s = "any old string";
        s += "";
    }
}

javap -c EmptyString:

Compiled from "EmptyString.java"
class EmptyString extends java.lang.Object{
EmptyString();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   ldc     #2; //String any old string
   2:   astore_1
   3:   new     #3; //class java/lang/StringBuilder
   6:   dup
   7:   invokespecial   #4; //Method java/lang/StringBuilder."":()V
   10:  aload_1
   11:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   14:  ldc     #6; //String
   16:  invokevirtual   #5; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   19:  invokevirtual   #7; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
   22:  astore_1
   23:  return

}

You can see that += causes a StringBuilder to be created regardless of what it's concatenating, so it can't be optimized at runtime.

On the other hand, if you put both String literals in the same expression, they are concatenated by the compiler:

class EmptyString {
    public static void main(String[] args) {
        String s = "any old string" + "";
    }
}

javap -c EmptyString:

Compiled from "EmptyString.java"
class EmptyString extends java.lang.Object{
EmptyString();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   ldc     #2; //String any old string
   2:   astore_1
   3:   return

}
like image 157
Michael Myers Avatar answered Nov 14 '22 21:11

Michael Myers


You'll get a new String after executing the line

s += "";

Java allocates a new String object and assigns it to s after the string concatenation. If you have eclipse handy (and I assume you can do the same thing in NetBeans, but I've only ever used eclipse) you can breakpoint that line and watch the object IDs of the object that s points to before and after executing that line. In my case, the object ID of s before that line of code was id=20, and afterward was id=24.

like image 28
Peter Avatar answered Nov 14 '22 22:11

Peter