Java JLS示例3.10.5-1之间的差异。字符串文本和Oracle JDK? 规范

Java JLS示例3.10.5-1之间的差异。字符串文本和Oracle JDK? 规范,java,Java,Java语言规范第8部分告诉我们: 由编译单元组成的程序(§7.3): 及编制组: package other; public class Other { public static String hello = "Hello"; } 生成输出: true true true true false true 现实 但编译和运行时使用的是oracle jdk 1.8.0_65(win)输出 问题1 这有什么不同? (我有一个猜测,将公布答案) 问题2 这是规范中的错误还是编译器或解释器中的

Java语言规范第8部分告诉我们:


由编译单元组成的程序(§7.3):

及编制组:

package other;
public class Other { public static String hello = "Hello"; }
生成输出:

true true true true false true

现实 但编译和运行时使用的是oracle jdk 1.8.0_65(win)输出

问题1 这有什么不同? (我有一个猜测,将公布答案)

问题2 这是规范中的错误还是编译器或解释器中的错误

如果有任何此类情况,应向何处报告


版本 对问题1的答复 javac编译器在编译时进行优化

编译器将其识别为常量表达式:

String lo = "lo";
并得出结论,这一定也是一个常量表达式:

"Hel" + lo
因此,假设整个项是一个字符串值常量表达式,我们将一个内部字符串与一个相等的内部字符串进行比较。因此,我们比较相同的参考,得到
true
,完整的检查可以预先评估为true

证据
  • 字节码(
    javap-c
    )向我们展示了一些预计算。1,4中的表达式。五,。打印内容仅被替换为
    “true”
  • 以下代码解除优化:
  • 来源

    public class StringTest {
      public static void main(final String[] args) {
        final String hello = "Hello", lo = "lo";
        String myLo = "";
        if (Math.random() < 10) {
          myLo = "lo";
        }
        System.out.print((hello == "Hello") + " ");
        System.out.print((Other.hello == hello) + " ");
        // System.out.print((other.Other.hello == hello) + " "); // same package
        System.out.print((hello == ("Hel" + "lo")) + " ");
        System.out.print((hello == ("Hel" + lo)) + " ");
        System.out.print((hello == ("Hel" + myLo)) + " ");
        System.out.println(hello == ("Hel" + lo).intern());
      }
    }
    

    尽管JIT是聪明的,但是他的弟弟,编译器也不是完全愚蠢的。
    String lo = "lo";
    
    "Hel" + lo
    
    public class StringTest {
      public static void main(final String[] args) {
        final String hello = "Hello", lo = "lo";
        String myLo = "";
        if (Math.random() < 10) {
          myLo = "lo";
        }
        System.out.print((hello == "Hello") + " ");
        System.out.print((Other.hello == hello) + " ");
        // System.out.print((other.Other.hello == hello) + " "); // same package
        System.out.print((hello == ("Hel" + "lo")) + " ");
        System.out.print((hello == ("Hel" + lo)) + " ");
        System.out.print((hello == ("Hel" + myLo)) + " ");
        System.out.println(hello == ("Hel" + lo).intern());
      }
    }
    
    true true true true false true