如果Java编译器出现在变量之后,为什么不连接字符串文字?

Siq*_*Lin 10 java

我有以下测试代码:

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";
    }
}
Run Code Online (Sandbox Code Playgroud)

生成的字节码是:

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
}
Run Code Online (Sandbox Code Playgroud)

testPrefix()表达式中,表达式"a"+"b"由Java编译器组合成字符串文字"ab",但是在"a" + "b"表达式中,表达式"c"+"d"在编译时不被组合.

为什么编译器不能在第二种方法中组合String文字?源文件是使用默认的Oracle JDK 8 javac编译的.

ass*_*ias 17

因为字符串连接运算符(+)在语法上是左关联的:

例如,表达式:

a + b + c
Run Code Online (Sandbox Code Playgroud)

总是被视为含义:

(a + b) + c
Run Code Online (Sandbox Code Playgroud)

不可否认,如果bc是字符串,表达式相当于a + (b + c).因此,编译器可以在特定情况下执行您的建议,但规范并未强制要求......

  • 看起来,在“javac”的情况下,它确实从 Java 8、更新 92 开始优化了串联(在更新 60 中,它没有)。 (2认同)