java 变量作用域,变量可能尚未初始化

java variable scope, variable might not have been initialized

我在研究java,我知道Java变量作用域,比如class级,方法级,块级。 但是,当我尝试练习变量范围时,我遇到了代码中的错误。 我的代码如下:

public class HelloWorld {
    public static void main(String[] args) {
        int c;
        for (int i=0; i <5; i++) {
            System.out.println(i);
            c = 100;
        }
        System.out.println(c);
    }
}

当我 运行 此代码时,它显示错误:the c variable might not have been initialized,但是当我将代码更改为以下内容时:

public class HelloWorld {
    public static void main(String[] args) {
        int c=0;
        for (int i=0; i <5; i++) {
            System.out.println(i);
            c = 100;
        }
        System.out.println(c);
    }
}

代码将打印 100.

我应该如何理解代码中的作用域?

这不是范围问题。您的变量 c 是方法范围的,并且在整个 main 方法中可用。这是一个编译器功能。在编译时,它无法检查“for”循环是否会 运行 至少一次来初始化变量。这就是为什么它说当您尝试打印它时该变量可能尚未初始化。所以 c 可用于 print 方法,但编译器不确定它是否已初始化。

因为你不能确保变量 c 总是在循环中被初始化。例如,如果您的代码如下所示:

public class HelloWorld {
    public static void main(String[] args) {
        int c;
        for (int i=0; i <0; i++) {
            System.out.println(i);
            c = 100;
        }
        System.out.println(c);
    }
}

您的代码永远不会进入循环,因此变量 c 永远不会被初始化。这就是为什么 java 语言要求在循环外使用变量时在循环外初始化它。

在 Java 中,局部变量未使用默认值初始化(与 类 的字段不同)。从语言规范一(§4.12.5)可以读到以下内容:

A local variable (§14.4, §14.14) must be explicitly given a value before it is used, by either initialization (§14.4) or assignment (§15.26), in a way that can be verified using the rules for definite assignment (§16 (Definite Assignment)).

因为它是在 Java 语言规范中明确设置的,所以编译器不会尝试(也不应该)推断变量 c 将始终在循环内更新:

public class HelloWorld {
    public static void main(String[] args) {
        int c;
        for (int i=0; i <5; i++) {
            System.out.println(i);
            c = 100;
        }
        System.out.println(c);
    }
}

编译器严格执行标准并通知您违反其中一项规则并出现错误:

"variable c might not have been initialized"

因此,即使您的代码可以被正式证明是有效的,编译器 job 也不会尝试分析您的应用程序的 逻辑 局部变量初始化的规则也不依赖于此。编译器检查变量 c 是否根据 局部变量初始化规则 进行了初始化,并且 做出相应的反应 (例如, 显示 int c;) 的编译错误。