我在编写这段代码时遇到了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循环之前初始化年来修复它,但我想知道是否有另一种方法来实现我想要实现的目标。
答案 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
。