2014-09-03 52 views
3

我有上编译这段代码用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循环之前初始化一年来解决它,但我想知道是否有另一种方法来实现我想要实现的目标。

+1

只是初始化一年'-1' – EpicPandaForce 2014-09-03 14:18:44

+0

有了,你现在有,在“年份”变量尚未初始化,可能无法初始化代码。如果你的while循环不执行会怎么样?只需使用默认值,如-1。 – Marko 2014-09-03 14:21:06

+0

不要为程序流使用catch块。 – Stefan 2014-09-03 14:21:18

回答

6

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

+0

我希望它没有虽然抛出一个错误。如果它是一个警告,我能够理解,但一个错误让我觉得很不好我的代码:( – raphaelgontijolopes 2014-09-03 20:28:42

+0

作为@Zhuinden建议在评论中,初始化一年默认值当你声明它与编译器将不再产生错误。 – Julien 2014-09-04 07:26:21

2

不需要。您必须初始化。本地aka方法变量在使用之前必须被初始化。

本地变量不会得到默认值。在使用之前,你必须初始化它们。

0

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

0

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

1

试想一个情况,当 gotYear

while (!gotYear) 

评估为真正

在这种情况下,将不会被初始化,因为它在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编译器不计算表达式。因此得到了可以采取两个值之一 true false

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

0

year将不会被分配给Integer.parseInt(userInput);抛出一个NumberFormatException。

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使用boolean

+0

著名的和这么难看空“为(;;)”,并提醒我们的基本。 – Julien 2014-09-03 14:32:28

+0

的“破发”请问为什么使用的'布尔'优选(而不是'Boolean')? – raphaelgontijolopes 2014-09-03 14:40:33

+0

布尔是基本类型(如int),其中包含的假真布尔是一个子类对象的,并持有一个布尔值,它因此可以为空了。 – 2014-09-03 14:51:59