首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >表达式可以在编译时求值吗?

表达式可以在编译时求值吗?
EN

Stack Overflow用户
提问于 2012-12-09 17:56:14
回答 4查看 1.3K关注 0票数 1
代码语言:javascript
运行
复制
public class Test1 {
    static final int i;
    static{
        if(3<2){
        i = 0;
        }
    }   
}
代码语言:javascript
运行
复制
public class Test2 {
    static final int i;
    static{
        if(3>2){
        i = 0;
        }
    }   
}

Test1编译失败,类Test2编译成功。

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

EN

回答 4

Stack Overflow用户

发布于 2012-12-09 18:00:34

代码语言:javascript
运行
复制
static final int i;

需要在静态初始化器中初始化,因为它是最终的。

代码语言:javascript
运行
复制
static{
        if(3<2){
        i = 0;
        }
    }

由于3<2文字或常量,编译器能够检测到代码的无效部分,并且不会初始化i。

添加一个else用例并在其中执行一些i初始化。

票数 5
EN

Stack Overflow用户

发布于 2012-12-09 18:06:28

它与编译器如何确定语句是否将被执行有关。它是在JLS #16中定义的

每个局部变量和每个空的最终字段在其值发生任何访问时都必须有一个明确分配的值。

在您的示例中,编译器可以确定在编译时是否明确分配了i,因为if中的表达式是常量表达式。

JLS #15.28定义常量表达式

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

  • 原语类型的文字...
  • 关系运算符<、<=、>和>= ...

有趣的是,尽管Test2可以编译,但这个修改后的Test2版本不能编译:

代码语言:javascript
运行
复制
static class Test3 {
    static final int i;
    static {
        int j = 3;
        if (j > 2) {
            i = 0;
        }
    }
}

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

票数 2
EN

Stack Overflow用户

发布于 2012-12-09 18:08:49

根据Java Language Specification的说法,if语句的条件部分中的表达式是编译时表达式。在Test1编译器知道我永远不会被初始化,这就是为什么它会报错。在第二种情况下,编译器知道我将被初始化。如果将编译时表达式替换为更动态的表达式,两个类都将无法编译,因为编译器不能保证我已被初始化。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13786424

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档