Java 表达式可以在编译时计算吗?

Java 表达式可以在编译时计算吗?,java,static,final,Java,Static,Final,类Test1未能编译, 类Test2已成功编译 有谁能告诉我编译器是如何在if条件下计算表达式的 public class Test2 { static final int i; static{ if(3>2){ i = 0; } } } 需要在静态初始值设定项处初始化,因为它是最终的 static final int i; 静态{ 如果(3) 需要在静态初始值设定项处初始化,因为它是最终的 static f

Test1
未能编译, 类
Test2
已成功编译

有谁能告诉我编译器是如何在if条件下计算表达式的

public class Test2 {
    static final int i;
    static{
        if(3>2){
        i = 0;
        }
    }   
}
需要在静态初始值设定项处初始化,因为它是最终的

static final int i;
静态{
如果(3)
需要在静态初始值设定项处初始化,因为它是最终的

static final int i;
静态{

if(3与编译器如何确定是否执行语句有关。定义如下:

当对其值进行任何访问时,每个局部变量和每个空白最终字段都必须有一个明确的赋值

在您的示例中,编译器可以确定
i
在编译时是否被明确赋值,因为
if
中的表达式是常量表达式

定义常量表达式:

编译时常量表达式是一个表示原语类型的值或字符串的表达式,该值或字符串不会突然完成,并且仅使用以下内容组成:

  • 基元类型[…]的文本
  • 关系运算符=[…]
有趣的是,这个修改后的Test2版本没有编译,尽管Test2编译:

static{
        if(3<2){
        i = 0;
        }
    }

原因是
j>2
不再是一个常量表达式。使j
final
将使类再次编译。

它与编译器如何确定语句是否将被执行有关。它定义在:

当对其值进行任何访问时,每个局部变量和每个空白最终字段都必须有一个明确的赋值

在您的示例中,编译器可以确定
i
在编译时是否被明确赋值,因为
if
中的表达式是常量表达式

定义常量表达式:

编译时常量表达式是一个表示原语类型的值或字符串的表达式,该值或字符串不会突然完成,并且仅使用以下内容组成:

  • 基元类型[…]的文本
  • 关系运算符=[…]
有趣的是,这个修改后的Test2版本没有编译,尽管Test2编译:

static{
        if(3<2){
        i = 0;
        }
    }
原因是
j>2
不再是一个常量表达式。使j
final
将使类再次编译。

根据条件中的表达式,if语句的部分是编译时表达式。在Test1中,编译器知道我永远不会被初始化,这就是它抱怨的原因在这种情况下,编译器知道i将被初始化。如果用更动态的内容替换编译时表达式,两个类都将无法编译,因为编译器无法保证i已初始化。

根据条件中的表达式,If语句的部分是编译时表达式。在st1编译器知道我永远不会被初始化,这就是它抱怨的原因。在第二种情况下,编译器知道我会被初始化。如果用更动态的东西替换编译时表达式,两个类都将无法编译,因为编译器将无法保证我被初始化。

If(32)
可以优化为
if(true)
,然后始终执行随附的语句。这没有问题

编译器可以很容易地检测到这些是常量标量,因此可以在编译时计算(即优化)表达式。我们对一个好的编译器的期望是一样的。

if(32)
可以优化为
if(true)
,然后始终执行附带的语句。这没有问题

编译器可以很容易地检测到这些是常量标量,因此可以在编译时计算(即优化)表达式。我们对一个好的编译器的期望是一样的