Java 预处理器

45

如果我有一个布尔类型的字段:

private static final boolean DEBUG = false;

并且在我的代码中,我有像这样的语句:

if(DEBUG) System.err.println("err1");

Java预处理器是不是只是摆脱if语句和无法到达的代码?


2
Java语言没有预处理器,(http://java.sun.com/developer/JDCTechTips/2003/tt0408.html)你是在谈论Java编译器吗? - S.Lott
谢谢这篇文章,我不知道Java没有预处理器。所以我只是在谈论编译器。 - twolfe18
Java确实没有像C/C++那样具有相同功能的预处理器。但是它确实有注解处理器,可以在编译时进行处理。请参阅Oracle的注解教程 - KomodoDave
上面的链接已经失效了...现在应该是https://docs.oracle.com/javase/tutorial/java/annotations/。 - Perry
2个回答

117

大多数编译器会消除该语句。例如:

public class Test {

    private static final boolean DEBUG = false;

    public static void main(String... args) {
        if (DEBUG) {
            System.out.println("Here I am");
        }
    }

}

编译这个类之后,我通过javap命令打印生成的指令清单:

javap -c Test
    Compiled from "Test.java"
    public class Test extends java.lang.Object{
    public Test();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."":()V
       4:   return
public static void main(java.lang.String[]); Code: 0: return
}

可以看到,没有System.out.println! :)


2
另外,我检查了一下,当你有一个类似于 if(DEBUG && condition_that_may_be_true) ... 的语句时,如果 DEBUG 总是为 false,它就会被剪掉。 - twolfe18

13

是的,Java编译器会消除由常量控制的if块内的编译代码。这是一种可以接受的方式,用于条件编译“调试”代码,您不想将其包含在生产构建中。


你能给出说明这个的Java语言规范页面吗? - Ralph
3
@Ralph: 请查看JLS中的14.21不可访问语句部分,了解讨论内容。 关于if语句的内容就在该部分末尾。 - Greg Hewgill
1
现在可以在以下网址找到JSE7的页面:http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.21,而JSE5的页面则在这里:http://docs.oracle.com/javase/specs/jls/se5.0/html/statements.html#14.21。 - user146043

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接