首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >为什么Java编译器不能理解这个变量总是被初始化?

为什么Java编译器不能理解这个变量总是被初始化?
EN

Stack Overflow用户
提问于 2012-11-05 23:49:05
回答 3查看 3.7K关注 0票数 54
class Foo{
    public static void main(String args[]){
        final int x=101;

        int y;
        if(x>100){
            y=-1;
        }
        System.out.println(y);
    }
}

Java编译器理解if语句的条件始终为真,因此y将始终被初始化。正如预期的那样,没有编译错误。

class Bar{
    public static void main(String args[]){
        final int x;
        x=101;

        int y;      
        if(x>100){
            y=-1;
        }
        System.out.println(y);
    }
}

但是当我将x的声明和初始化分成两行时,编译器似乎并不知道条件总是为真,而y总是会被初始化。

final int x;
x=101;
byte b;
b=x;
System.out.println(b);

同样的事情也会发生在这里,编译器会给出精度损失的错误。

final int x=101;
byte b;
b=x;
System.out.println(b);

同样,编译器可以理解x在b的范围内。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-11-05 23:57:53

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

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

在您的例子中,编译器不能确定y已被明确赋值,并给出一个错误。这是因为它需要确定条件始终为真,而这只有在if中的条件是常量表达式时才有可能。

JLS #15.28定义常量表达式

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

  • ...
  • 引用常量变量的简单名称(§6.5.6.1) (§4.12.4)。

JLS #4.12.4将常量变量定义为:

基本类型或字符串类型的变量称为常量变量,它是最终类型,并使用编译时常量表达式进行初始化。

在您的例子中,final int x = 101;是一个常量变量,而final int x; x = 101;不是。

票数 27
EN

Stack Overflow用户

发布于 2012-11-05 23:56:18

作为可移植性目标的一部分,对于编译器应该接受什么和应该拒绝什么,有一组非常具体的规则。当确定变量在使用时是否被明确赋值时,这些规则既允许也只需要有限形式的流分析。

请参阅Java Language Specification Chapter 16. Definite Assignment

关键规则是16.2.7. if Statements中的规则,"if (e) S“。明确分配的规则扩展为:

V在if (e) S之后赋值当且仅当,V在S之后赋值,当为false时V在e之后赋值。

Y是相关的V。它在if语句之前未赋值。它确实是在S,y= {y=-1;}之后赋值的,但是当x>100为false时,没有任何东西使它赋值。

因此,在if语句之后没有明确地指定y。

更完整的流分析将确定条件x>100始终为真,但是编译器需要基于这些特定规则拒绝程序。

最后一个变量没有问题。规则实际上是:-

“如果最后一个变量被赋值,则它是编译时错误,除非它在赋值之前被明确取消赋值(§16)。”

声明肯定是未赋值的,即使是有限流分析也可以确定x在赋值时仍然是绝对未赋值的。

票数 46
EN

Stack Overflow用户

发布于 2012-11-06 00:13:25

您对第二段代码中的变量x做了什么,称为空白最终变量。如果一个最终变量在声明时没有初始化,那么它就是一个空白的最终变量。

许多Java开发人员认为final变量的值在编译时是已知的。这并非总是正确的。据说空白最终变量的值在编译时是未知的。因此,您的第二个代码将给您一个编译错误。编译器可以看到您已经初始化了最后一个变量x,但是compile不知道它的值。所以编译器不能解析if语句。因此,它认为变量y没有初始化。

您可以阅读更多关于Java final variables here的内容。

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

https://stackoverflow.com/questions/13235559

复制
相关文章

相似问题

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