javac 根据赋值方法不同地对待 static final

问题描述 投票:0回答:4

当我编译时:

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

java class javac final
4个回答
7
投票

在第一种情况下,编译器会进行优化。它知道

Foo
将永远是
false
,并杀死永远无法达到的代码。

在第二种情况下,您将非最终变量

isBar
的值分配给
BAR
。编译器无法判断变量
isBar
是否已在其他地方被修改,特别是如果它不是私有的。因此不确定
BAR
的值。因此他无法进行优化。


2
投票

这纯粹是编译器优化的情况,它忽略直接赋值并考虑文字的间接赋值。


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


        }
   }

}

你可以使用一些反编译工具查看编译后的代码,你会发现我在类文件中编写的优化方法。


0
投票

内存中可能只有一个存在的静态值。在第一个块中,静态最终变量

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

© www.soinside.com 2019 - 2024. All rights reserved.