[英]javac code elimination capabilities
我很难找到有关javac
的代码消除功能的信息:
我读到,如果您有类似以下内容, if
if-语句将被消除:
static final boolean DEBUG = false;
if (DEBUG) System.out.println("Hello World!"); // will be removed
但是,例如:
static final int VALUE = 3;
if (VALUE > 9) System.out.println("VALUE > 9 ???"); // will this be removed?
或这个:
static final SomeEnum VALUE = SomeEnum.FOO;
if (VALUE==SomeEnum.BAR) System.out.println("Bar???"); // will this be removed?
因为很难/不可能分析程序来查找所有无效代码(可能类似于暂停问题),所以我可以想象只有少数定义良好的构造(如上面的第一个示例), javac
可以识别并可靠地移除。 是否有这些结构的完整列表?
亚述似乎已经找到了答案(让我把它们全部放在一起):
第二章“14.21。不可达语句”的JLS规定,即,在一般情况下,代码中的任何不到的语句被认为是一个编译时错误,唯一的例外是一种特殊的待遇if
-statements特别允许有条件编译。
因此, 可能导致代码消除的唯一构造(如果编译器选择这样做的话!)是:
if (compileTimeConstantExpression) {
doThis(); // may be removed if compileTimeConstantExpression == false;
} else {
doThat(); // may be removed if compileTimeConstantExpression == true;
}
(当然, else
-part是可选的)
不允许进行代码消除的所有其他构造,例如while (false) ...
,都是不允许的,并且会引起编译时错误,而不是导致条件编译。
组成可接受的compileTimeConstantExpression
的定义可以在JLS的“ 15.28。常量表达式”一章中找到。 可以在这里找到另一个带有更多示例的精彩页面: Java中的编译时间常数
注意:不需要编译器删除if
-stament的“ unreachable”部分。 javac
似乎可以可靠地做到这一点,但是其他编译器可能没有。 唯一可以确定的方法是通过反编译检查输出,例如,使用Jon Skeet建议的javap -c
。
我看到第二个例子也被删除了
这是我的课
public class Test {
public static void main(String[] args) throws Exception{
final int VALUE = 3;
if (VALUE > 9) System.out.println("VALUE > 9 ???");
}
}
这是反编译的版本
Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]) throws java.lang.Exception;
Code:
0: return
}
我的猜测是这是特定于实现的(Oracle,IBM等)。
如果您对Oracle版本感兴趣,可以从OpenJDK项目开始寻找资源: http : //openjdk.java.net/groups/compiler/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.