当我编译时:
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中有两种不同“类型”的静态final,或者这只是编译器优化?
在第一种情况下,编译器会进行优化。它知道
Foo
将永远是 false
,并杀死永远无法达到的代码。
在第二种情况下,您将非最终变量
isBar
的值分配给 BAR
。编译器无法判断变量 isBar
是否已在其他地方被修改,特别是如果它不是私有的。因此不确定BAR
的值。因此他无法进行优化。
这纯粹是编译器优化的情况,它忽略直接赋值并考虑文字的间接赋值。
在第一种情况下,
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
}
}
}
你可以使用一些反编译工具查看编译后的代码,你会发现我在类文件中编写的优化方法。
内存中可能只有一个存在的静态值。在第一个块中,静态最终变量
FOO
被设置为编译器已知的假值,因此它优化了其中的if语句。但是在第二条语句中,BAR
最终静态变量被分配了isBar
静态变量值,这反过来又使得编译器不会优化if语句(因为isBar
可以是任何布尔值,并且无法确定,因为java支持 polymorphism
并且在运行时动态地将值分配给变量。),因此第二个块中的静态变量内存位置对于编译器确定其值非常重要,而在第一个块中,值 false 是已知的,无需任何赋值不同变量之间进行优化。