当前位置: 首页 > 面试题库 >

为什么Java编译器不理解此变量总是初始化的?

方高丽
2023-03-14
问题内容
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语句的条件始终为true,因此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的声明和初始化分为两行时,编译器似乎没有得到条件始终为true且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的范围内。


问题答案:

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

每个局部变量和每个空白的final字段在对其值进行任何访问时都必须具有一个明确分配的值。

在您的情况下,编译器无法确定y已被明确分配,并给您一个错误。这是因为它将需要确定条件始终为真,并且仅当中的条件if常量表达式时 才有可能。

JLS#15.28定义
常量表达式

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

  • […]
  • 引用常量变量(第4.12.4节)的简单名称(第6.6.5.6.1节)。

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

最终类型并使用编译时常量表达式初始化的基本类型或String类型的变量称为常量变量。

在您的情况下,final int x = 101;是一个常量变量,但final int x; x = 101;不是。



 类似资料:
  • Java编译器知道if语句的条件总是true,因此y总是被初始化的。正如预期的那样,没有编译错误。 但是当我把x的声明和初始化分成两行时,编译器似乎没有得到条件总是真的,y总是被初始化的。 这里也会发生同样的情况,编译器会给出精度损失错误。 同样,编译器可以理解x在b的范围内。

  • 问题内容: Java的设计者是否有任何理由认为不应为局部变量提供默认值?认真地讲,如果实例变量可以被赋予默认值,那为什么我们不能对局部变量做同样的事情呢? 问题答案: 声明局部变量主要是为了进行一些计算。因此,程序员决定设置变量的值,并且不应采用默认值。如果程序员错误地没有初始化局部变量并且使用默认值,则输出可能是一些意外值。因此,在使用局部变量的情况下,编译器将要求程序员在访问变量之前使用一些值

  • 问题内容: 我已经搜索了很多,并在此处给出的堆栈溢出中得到了这个答案 那说明我们可以同时使用构造函数和简单初始化 但我想要答案 但是,如果编译器自动完成构造函数初始化,为什么还要使用构造函数初始化呢! 问题答案: 构造函数的简单定义: 初始化类对象的特殊方法。始终且仅与关键字一起使用以创建类的实例。 与类的名称相同。 可以接受一个或多个参数。 没有返回值,甚至没有void。 默认构造函数不带任何参

  • 问题内容: print语句导致以下编译时错误, 局部变量f可能尚未初始化 如果Java中的原语已经具有默认值(float = 0.0f) ,为什么需要定义一个? 所以这有效 感谢大家! 问题答案: 因为它是一个局部变量。这就是为什么什么都没有分配的原因: 局部变量略有不同。编译器永远不会为未初始化的局部变量分配默认值。如果您无法在声明它的地方初始化本地变量,请确保在尝试使用它之前为其分配一个值。访

  • print语句会导致以下编译时错误, 局部变量f可能尚未初始化 如果Java中的原语已经有一个默认值(float=0.0f),为什么我需要定义一个呢? 所以,这是有效的 谢谢大家!

  • (这个问题与此密切相关,但它是一个更具体的问题,我希望能就此得到答案)