javac代码消除能力

bvk5enib  于 2023-03-28  发布在  Java
关注(0)|答案(4)|浏览(116)

我很难找到有关javac代码消除功能的信息:
我读到如果你有类似下面的东西,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可以识别并可靠地删除。

jv4diomz

jv4diomz1#

阿西利亚斯似乎已经找到了答案(让我把它们放在一起):
JLS的“14.21.不可达语句”一章规定,一般来说,代码中任何不可达语句都被认为是编译时错误,唯一的例外是对if语句的特殊处理,以专门允许条件编译。
因此,only构造可能导致代码消除(如果编译器选择这样做!)是:

if (compileTimeConstantExpression) {
    doThis(); // may be removed if compileTimeConstantExpression == false;
} else {
    doThat(); // may be removed if compileTimeConstantExpression == true;
}

(the else-当然,部件是可选的)
所有其他允许代码消除的构造,例如while (false) ...,都是不允许的,并且会导致编译时错误,而不是导致条件编译。
可接受的compileTimeConstantExpression的定义可以在JLS的“15.28.常量表达式”一章中找到。另一个包含更多示例的页面可以在这里找到:Compile Time Constants in Java

  • 注意:编译器不需要移除if-stament的“unreachable”部分。javac似乎可以可靠地执行此操作,但其他编译器可能做不到。唯一确定的方法是通过反编译检查输出,例如使用Jon Skeet建议的javap -c。*
dxxyhpgq

dxxyhpgq2#

我已经运行了一些测试,如果条件是一个计算结果为false的常量表达式,javac似乎(逻辑上)会删除代码。
总之,常量表达式是仅使用常量作为操作数的表达式,即原语,字符串字面量和final原语或已用常量值初始化的Strings变量。
请注意,这是编译器相关的,因为JLS并不强制编译器像14.21节最底部所解释的那样智能:
优化编译器可以认识到语句x=3;将永远不会被执行,并且可以选择从生成的类文件中省略该语句的代码。

31moq8wy

31moq8wy3#

我看到第二个例子也被删除了
这是我的课

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

}
k5ifujac

k5ifujac4#

我的猜测是,这是特定于实现的(Oracle,IBM,...)。
如果您对Oracle的版本感兴趣,那么开始寻找资源的好地方是OpenJDK项目:http://openjdk.java.net/groups/compiler/

相关问题