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.
It’s bytecode time!
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 aStringBuilderto 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:
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 }