java “变量可能尚未初始化”,即使我确定它是

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25646698/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 08:23:47  来源:igfitidea点击:

"variable might not have been initialized" even though I make sure it is

javatry-catchjavac

提问by raphaelgontijolopes

I am having trouble with Javac on compiling this piece of code:

我在编译这段代码时遇到了 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 gives me the error on line return year;that "variable 'year' might not have been initialized". But since it's inside a while loop, I know for sure it will have been initialized. I asked my T.A. about this and he was not able to answer me why this happens. His best guess is that Javac is not a very good compiler for figuring this kind of stuff out.

Javac 在线给出了return year;“变量‘年份’可能尚未初始化”的错误。但由于它在一个 while 循环中,我确信它会被初始化。我就此问过我的助教,他无法回答我为什么会发生这种情况。他最好的猜测是 Javac 不是一个很好的编译器来解决这类问题。

Basically, why is this error happening? I know I can fix it by initializing year before I enter the while loop, but I wanted to know if there is another way of achieving what I'm trying to achieve.

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

回答by Julien

Your year variable is initialized in a try block. It's obvious to us that it won't get out the loop until something OK is input. But the compiler's rules are simpler than that : as the initialisation can be disrupted by an exception, it considers that year may be uninitialized.

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

回答by Suresh Atta

No. You have to initialize. Local aka method variables must gets initialized before they use.

不,你必须初始化。本地又名方法变量必须在使用之前进行初始化。

Local variable won't get default values. You have to initialize them, before you use.

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

回答by Vaibhav Raj

Imagine a situation when gotYearin

想象一下当gotYear进入时的情况

while (!gotYear)

evaluates to true.

评估为true

In this case yearwill not be initialized, as it is inside the while loop.

在这种情况下,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();
    }
}

At the time of compilation java compiler doesn't evaluates expressions. Therefore gotYearcan take either of two values trueor false.

在编译时,java 编译器不评估表达式。因此gotYear可以采用两个值truefalse 中的任何一个

Local variables should be initialized within the same scope in which they are declared. Intialization should be done before using it.

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

回答by Joop Eggen

yearwill not be assigned to when Integer.parseInt(userInput);throws a NumberFormatException.

yearInteger.parseInt(userInput);抛出 NumberFormatException时不会分配给。

That gotYearthen remains Boolean.FALSE keeping in the loop, is too complex for the compiler. It thinks you might exit the loop somehow.

gotYear则保留在循环Boolean.FALSE饲养,是编译器太复杂。它认为您可能会以某种方式退出循环。

The following should behave better.

以下应该表现得更好。

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

Maybe the compiler just might accept:

也许编译器可能会接受:

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

BTW better use booleaninstead of the Object wrapper class Boolean.

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

回答by Mind Peace

You must initialize local variables. Go through Thisto understand basics

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

回答by kirti

Local variables are used mostly for intermediate calculations whereas instance variables are supposed to carry data for calculations for future and intermediate as well. Java allows default value for instance variables but for local variables its required to assign the value. So to avoid mistakes you need to initialize local variables.

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