5

当我编译时:

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“类型”,或者这只是编译器优化?

4

4 回答 4

7

在第一种情况下,编译器会进行优化。它知道Foo将永远存在false并杀死代码,而不是永远无法到达。

在第二种情况下,您将非最终变量的值分配isBarBAR. 编译器无法判断变量isBar是否已在其他地方修改,特别是如果它不是私有的。因此不确定 的值BAR。因此他无法进行优化。

于 2013-07-26T15:31:09.313 回答
2

In the first case static final fields are constants which are known at compile time. So the compiler optimizes and inlines the constant.

In the second case the field is non-final variable and cannot be inlined by the compiler as it can change.

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


        }
   }

}

You can look at the compiled code using some de-compiler tools and you will find the optimized method that I have written in the class file.

于 2013-07-26T15:32:01.810 回答
2

It is purely a case of compiler optimization where it ignores a direct assignment and does consider indirect assignment of literals.

于 2013-07-26T15:34:32.317 回答
0

内存中可能只有一个现有的静态值。在第一个块中,静态最终变量FOO被设置为编译器已知的 false 值,因此它优化了其中的 if 语句。但是在第二条语句中,BAR最终的静态变量被分配了isBar静态变量值,这反过来又使编译器不优化 if 语句(因为isBar可以是任何布尔值并且无法确定,因为 java 支持polymorphism并且值是动态分配给变量的)运行时。),因此第二个块中的静态变量内存位置对于编译器确定其值很重要,其中与第一个块中一样,值 false 是已知的,无需在不同变量之间进行任何分配,并且已对其进行了优化。

于 2013-07-26T15:41:51.590 回答