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.
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.
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 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.
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.
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 }
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With