javac根据赋值方法不同地处理静态final
当我编译:
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
的值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
被设置为false值,这是编译器已知的,因此它优化了if语句。 但是在第二个语句中, BAR
最终静态变量被赋予isBar
静态变量值,这反过来使得编译器不会优化if语句(因为isBar
可以是任何布尔值,并且由于java支持polymorphism
并且值被赋值,所以无法确定它在运行时动态变量。)因此,第二个块中的静态变量内存位置对于编译器确定其值很重要,其中在第一个块中,值false是已知的,不需要在不同变量之间进行任何分配,并且它是优化的。