Mar*_* A. 12 java compiler-construction dead-code constant-expression code-elimination
随着讨论这里,javac的和其他Java编译器可以提供代码消除能力if-statements这里的条件是"常量表达式".
如果我的代码使用依赖于不同包中定义的其他常量表达式的常量表达式,这会受到什么影响?
例如,假设我在相应的指定包中有以下类:
package foo;
public class Foo {
    public static final boolean CONDITION = false;
}
和
package bar;
import foo.Foo;
public class Bar {
    public void test() {
        if (Foo.CONDITION) {
            System.out.println("This line of code could be eliminated.");
        } else {
            System.out.println("This line of code will be executed.");
        }
    }
}
显然,如果foo-package是在从外部JAR文件运行时加载,编译器不能在技术上只是假设,Foo.CONDITION将是错误的,不应该消除true的分枝的if语句来.
然而,如果Foo并且Bar实际上在同一个包中,则true应该绝对消除-branch(如果编译器完全支持代码消除).
不太确定如何最好短语这个问题,但:如何"亲密"也Foo必须是Bar常量表达式在Foo中也被认为是恒定Bar?他们需要在同一个档案中吗?同样的包裹?相同的jar文件?或者它根本不重要(即编译器是否始终认为Foo.CONDITION是常量并使用编译时在构建路径中找到的值)?
由于它是引用类的公共"签名"的一部分,因此它被假定为常量.基本上这个想法final意味着最终,如果你改变它,那就是你的错.
这类似于引用类的实际方法签名,也在编译时按原样使用.这就是为什么如果你针对一个版本的库编译代码并对另一个版本运行它,你可能会得到一个NoSuchMethodError.
更新:实际上JLS 提供了更强大的保证:
如果字段是常量变量(§4.12.4),则删除关键字final或更改其值不会破坏与预先存在的二进制文件的兼容性,导致它们不能运行,但是它们不会看到任何新的用法值该字段除非重新编译.这是真实的,即使使用本身是不是编译时间常量表达式(§15.28).
这个结果是决定支持条件编译的副作用,如§14.21结尾所述.
| 归档时间: | 
 | 
| 查看次数: | 396 次 | 
| 最近记录: |