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是已知的,不需要在不同变量之间进行任何分配,并且它是优化的。