Java If(false)编译

时间:2011-06-04 23:23:28

标签: java tomcat

我正在使用Tomcat开发动态Web项目。拥有一个全局标志是很有用的,这是我在开发和部署服务器之间唯一需要更改的标志。该标志的最大用途是使用print语句。

public class Debug {
    public final static boolean DEVEL = true;        
    public static void print(String message){
        if(DEVEL){
            System.out.println(message);
        }
    }
}

我的问题是,java会编译出print语句。即如果devel标记为false,则消息显然不会打印,但它们将包含在类文件中(devel是final)。这是一个效率问题。我听说java编译器很聪明,但它会接受这个。

5 个答案:

答案 0 :(得分:14)

使用'final'属性(就像你一样),它将编译代码:

public static final boolean DEVEL = false;

您可以通过在结果类文件中搜索一个仅在编译代码时才会出现的字符串来进行检查。

答案 1 :(得分:6)

看一下这篇文章:

http://www.javaworld.com/javaworld/jw-03-2000/jw-03-javaperf_4.html

您提供的代码称为“死代码”,因此如果您将DEVEL设置为false,它将不会包含在已编译的类文件中,它将不会包含在字节码中。

另外,检查命令

javap -c

查看您班级的结果字节码。

答案 2 :(得分:1)

如果您希望编译器将其编译出来,请使用:

    public final static boolean DEVEL = Math.random() > -1;

编译器不会知道这始终是true。 (当然使用< -1的{​​{1}}

当你想暂时删除代码而不让编译器抱怨死代码时,我发现这个技巧很方便,例如:

false

答案 3 :(得分:0)

我从未见过编译器删除这样的代码,但是JIT会有效地删除从未运行过的代码。断言是一个常见的用例。可能仍然存在名义成本,但通常不值得担心。即小于1纳秒。

答案 4 :(得分:0)

如果消息的toString()方法成本很高,则成本可能会更高。预准备语句中的大型SQL查询的toString方法由于此行而导致堆溢出。因此标准没有删除它。