编译时:
public static final boolean FOO = false;
public static final void fooTest() {
if (FOO) {
System.out.println("gg");
}
}
我得到一个空方法fooTest() {}
。但是当我编译时:
static boolean isBar = false;
public static final boolean BAR = isBar;
public static final void fooTest() {
if (BAR) {
System.out.println("gg");
}
}
if语句包含在已编译的类文件中。这是否意味着java中有两种不同的“static”类型,或者这只是一种编译器优化?
答案 0 :(得分:7)
在第一种情况下,编译器进行优化。它知道Foo
永远是false
并且会杀死代码,而不是永远无法达到的代码。
在第二种情况下,您要将非最终变量isBar
的值分配给BAR
。编译器无法判断变量isBar
是否在其他地方被修改过,特别是如果它不是私有的。因此,它不确定BAR
的值。因此他不能做优化。
答案 1 :(得分:2)
在第一种情况下,static final
字段是在compile
时间已知的常量。因此,编译器优化并内联 constant
。
在第二种情况下,字段为non-final
variable
,并且编译器无法对其进行内联,因为它可以更改。
class Test{
public static final boolean BOOL = true; //CONSTANT KNOWN AT COMPILE TIME
public void someMethod(){
while(BOOL){
//some code
}
}
//OPTIMIZED VERSION DONE BY COMPILER
public void someMethod(){
while(true){ //There is no need for accessing BOOL if it is not going to change and compiler understands that so inlines the value of constant
}
}
}
您可以使用一些解编译工具查看已编译的代码,您将找到我在类文件中编写的优化方法。
答案 2 :(得分:2)
纯粹是编译器优化的一种情况,它忽略了直接赋值,并考虑间接赋值文字。
答案 3 :(得分:0)
内存中只能存在一个静态值。在第一个块中,静态最终变量FOO
设置为false值,编译器已知它,因此它优化了if语句。但在第二个语句中,BAR
最终静态变量被赋予isBar
静态变量值,这反过来又使编译器不优化if语句(因为isBar
可以是任何布尔值,它无法确定,因为java支持polymorphism
并且值在运行时动态分配给变量。)因此,第二个块中的静态变量内存位置对于编译器确定其值很重要,如第一个块中所示如果知道值false,则不会在不同变量之间进行任何分配,并且会对其进行优化。