Java If(false)编译

我正在使用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编译器很聪明,但它会接受这个。

使用’final’属性(就像你做的那样),它将编译出代码:

public static final boolean DEVEL = false;

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

看看这篇文章:

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

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

另外,检查命令

 javap -c 

查看类的结果字节码。

如果你想让编译器没有编译出来,请使用:

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

编译器不会知道这总是true 。 (当然使用< -1表示false

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

 void myMethod() { // temporarily exit early if (Math.random() > -1) return; // usual code } 

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

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