Why doesn't the Java compiler concatenate string literals if they appear after a variable?

java

Solution

Because the string concatenation operator (+) is syntactically left associative:

For example, the expression:

a + b + c

is always regarded as meaning:

(a + b) + c

Admittedly, if `b` and `c` are strings, the expression is equivalent to `a + (b + c)`. So a compiler could do what you suggest in that specific situation, but it is not mandated by the specification...

Problem

I have the following test code: ``` public class StringLiteralTest { static void testPrefix() { int i = 0; String prefixConcat = "a" + "b" + i; } static void testSuffix() { int i = 0; String suffixConcat = i + "c" + "d"; } } ``` The generated bytecode is: ``` Compiled from "StringLiteralTest.java" public class StringLiteralTest { public StringLiteralTest(); Code: 0: aload_0 1: invokespecial #8 // Method java/lang/Object."<init>":()V 4: return static void testPrefix(); Code: 0: iconst_0 1: istore_0 2: new #15 // class java/lang/StringBuilder 5: dup 6: ldc #17 // String ab 8: invokespecial #19 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 11: iload_0 12: invokevirtual #22 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 15: invokevirtual #26 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 18: astore_1 19: return static void testSuffix(); Code: 0: iconst_0 1: istore_0 2: new #15 // class java/lang/StringBuilder 5: dup 6: iload_0 7: invokestatic #35 // Method java/lang/String.valueOf:(I)Ljava/lang/String; 10: invokespecial #19 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V 13: ldc #41 // String c 15: invokevirtual #43 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 18: ldc #46 // String d 20: invokevirtual #43 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 23: invokevirtual #26 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 26: astore_1 27: return } ``` In `testPrefix()`, the expression `"a" + "b"` is combined into the string literal `"ab"` by the Java compiler, but in `testSuffix()`, the expression `"c" + "d"` is not combined at compile-time. Why can't the compiler combine the String literals in the second method? The source file was compiled with the default Oracle JDK 8 javac.

Original source