我经常使用布尔值来控制输出以进行调试:
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
}
答案 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"部分。