"变量可能尚未初始化"即使我确定它是

时间:2014-09-03 14:15:56

标签: java try-catch javac

我在编写这段代码时遇到了Javac的问题:

public static int getYear() {
    Console input = System.console();
    Boolean gotYear = false;
    int year;

    String userInput = input.readLine();

    while (!gotYear) {
        try {
            year = Integer.parseInt(userInput);
            gotYear = true;
        } catch (Exception e) {
            System.out.print("Please insert a valid date. ");
            userInput = input.readLine();
        }
    }

    return year;
}

Javac在第return year;行给出了错误"变量'年'可能尚未初始化"。但是因为它在一个while循环中,我知道它肯定会被初始化。我问过T.A.关于这一点,他无法回答我为什么会这样。他最好的猜测是,Javac并不是一个很好的编译器,可以解决这类问题。

基本上,为什么会发生这种错误?我知道我可以通过在进入while循环之前初始化年来修复它,但我想知道是否有另一种方法来实现我想要实现的目标。

6 个答案:

答案 0 :(得分:7)

您的年份变量在try块中初始化。对我们来说很明显,在输入OK之前它不会出现循环。但编译器的规则比这简单:由于初始化可能会被异常中断,因此它认为年份可能未初始化。

答案 1 :(得分:2)

没有。你必须初始化。本地aka方法变量必须在使用之前初始化。

局部变量不会获得默认值。在使用之前,您必须初始化它们。

答案 2 :(得分:1)

想象一下当 gotYear

时的情况
while (!gotYear)

评估为 true

在这种情况下, year 将不会被初始化,因为它在while循环中。

while (!gotYear) {
    try {
        year = Integer.parseInt(userInput);
        gotYear = true;
    } catch (Exception e) {
        System.out.print("Please insert a valid date. ");
        userInput = input.readLine();
    }
}

在编译时,java编译器不会计算表达式。因此, gotYear 可以采用两个值 true false 中的任何一个。

应该在声明它们的同一范围内初始化局部变量。在使用之前应该进行初始化。

答案 3 :(得分:0)

您必须初始化局部变量。通过This了解基础知识

答案 4 :(得分:0)

局部变量主要用于中间计算,而实例变量应该携带用于未来和中间计算的数据。  Java允许实例变量的默认值,但对于局部变量,它需要分配值。因此,为了避免错误,您需要初始化局部变量。

答案 5 :(得分:0)

year抛出NumberFormatException时,

Integer.parseInt(userInput);将不会被分配。

然后gotYear仍然是Boolean.FALSE保持在循环中,对于编译器来说太复杂了。它认为你可能会以某种方式退出循环。

以下情况应该会更好。

for (;;) {
    try {
        year = Integer.parseInt(userInput);
        break;
    } catch (Exception e) {
        System.out.print("Please insert a valid date. ");
        userInput = input.readLine();
    }
}

也许编译器可能会接受:

for (boolean keepAsking = true; keepAsking; ) {
    try {
        year = Integer.parseInt(userInput);
        keepAsking = false;

BTW更好地使用boolean而不是Object包装器类Boolean