javac根据赋值方法不同地处理静态final

时间:2013-07-26 15:25:59

标签: java class compiler-construction 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中有两种不同的“static”类型,或者这只是一种编译器优化?

4 个答案:

答案 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,则不会在不同变量之间进行任何分配,并且会对其进行优化。