如果某些东西总是假的,它会被编译吗?

时间:2015-01-08 12:45:08

标签: java

我经常使用布尔值来控制输出以进行调试:

void fooBar() {

  boolean debug = false;

  if (debug) System.out.println("will this be in the compile if debug is false?");

  // code for the method

}

我想知道,如果这个布尔值在方法内声明为false。那么它会被编译吗? (因为它是多余的)。

如果我的解释不清楚,是否会按上述方式编译或像这样:

void fooBar() {

  // code for the method

}

2 个答案:

答案 0 :(得分:4)

是的,它将被编译并且它的字节码将被发送到类文件(至少由Oracle的编译器)。这很容易检查:

javac YourClass.java
javap -p -c YourClass

......看看结果。

如果您使用Oracle的HotSpot运行它,并且如果它是代码中的热点,那么如果它被JIT消除,我不会感到惊讶。

然而,作为HotLicks points out,向其添加final

void fooBar() {

  final boolean debug = false;
//^^^^^

  if (debug) System.out.println("will this be in the compile if debug is false?");

  // code for the method

}

...允许编译器为其发出字节码。代码仍然必须编译。

答案 1 :(得分:2)

如果控制变量是static final -

public class CondComp {
    static final boolean debug = false;
    public void doIt() {
        if (debug) System.out.println("Here we are");
    }
}

Compiled from "CondComp.java"
public class CondComp {
  static final boolean debug;

  public CondComp();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  public void doIt();
    Code:
       0: return
}

可以看出,println没有生成任何内容。

对于不相信者,debug设置为true的情况与此相同:

Compiled from "CondComp.java"
public class CondComp {
  static final boolean debug;

  public CondComp();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  public void doIt();
    Code:
       0: getstatic     #2                  // Field java/lang/System.out:Ljava/
io/PrintStream;
       3: ldc           #3                  // String Here we are
       5: invokevirtual #4                  // Method java/io/PrintStream.printl
n:(Ljava/lang/String;)V
       8: return
}

我的理解是,即使static final变量属于不同的类别,这也适用,但我从未尝试过。

此功能记录在"unreachable statements"的JLS部分,靠近该部分的底部,以及"binary compatibility for final fields and constants"部分。