编译器优化是否改变了以下代码中语句的执行?

Is the execution of statements in the following code changed by compiler optimization?

在一个问题中我发现下面的代码

public static void main(String[] args) {
/*1*/        int x;
/*2*/        boolean found = false;
/*3*/        if (!found)
/*4*/            x = -1;

/*5*/        System.out.println(x);
    }

有 x 不是 init.(initialized) 的编译器错误。我很惊讶编译器无法推理 init.特别是因为这段代码似乎不需要任何运行时推理,如下所示:

  1. 在指示的第 2 行,found 设置为 false
  2. 第 2 行和第 3 行之间没有代码。
  3. 所以到了第3行,!found必然是true所以init是必然的

我想知道这是否正确。我依稀记得编译器优化可以改变语句的执行顺序。这在这里起作用吗?是否有可能在第 3 行和第 4 行之前到达第 5 行?


环境
openjdk 15.0.2 2021-01-19
OpenJDK 运行时环境 (build 15.0.2+7-27)
OpenJDK 64 位服务器 VM(build 15.0.2+7-27,混合模式,共享)
javac 15.0.2 Windows10

看看我的(晚)。规范要求源代码分析。

这不是按照您建议的方式重新排序代码的情况;这会改变行为,这是被禁止的。

想想一般情况:如果在计算完成之前允许使用计算,那么没有什么是可预测的。

但是,在您此处的示例中,允许足够智能的编译器将生成的代码优化为(有效地)System.out.println(-1)。这两个变量实际上都不是必需的。

如果发生这样的事情,不会影响对definite assignment的必要检查。从逻辑上讲,简化发生在验证源代码之后。

您必须检查生成的字节码才能了解实际发生的情况。此外,在 Java 中,可以通过实时编译为本机代码来完成优化 'later'。