title: Why doesn't the Java compiler concatenate string literals if they appear after a variable?
body: <p>I have the following test code:</p>
  
  <pre><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";
      }
  }
  </code></pre>
  
  <p>The generated bytecode is:</p>
  
  <pre><code>Compiled from "StringLiteralTest.java"
  public class StringLiteralTest {
    public StringLiteralTest();
      Code:
         0: aload_0
         1: invokespecial #8                  // Method java/lang/Object."&lt;init&gt;":()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."&lt;init&gt;":(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."&lt;init&gt;":(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
  }
  </code></pre>
  
  <p>In <code>testPrefix()</code>, the expression <code>"a" + "b"</code> is combined into the string literal <code>"ab"</code> by the Java compiler, but in <code>testSuffix()</code>, the expression <code>"c" + "d"</code> is not combined at compile-time.</p>
  
  <p>Why can't the compiler combine the String literals in the second method? </p>
  
  <p>The source file was compiled with the default Oracle JDK 8 javac.</p>