【问题标题】:java variable scope, variable might not have been initializedjava变量作用域,变量可能没有被初始化
【发布时间】:2021-04-01 22:05:00
【问题描述】:

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

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

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

【问题讨论】:

    标签: java variables scope


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      因为你不能确保变量 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 语言要求你在循环外使用一个变量,如果你在循环外使用它。

      【讨论】:

        【解决方案3】:

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

        必须明确地给局部变量(§14.4、§14.14)赋值 在使用之前,通过初始化(第 14.4 节)或赋值 (§15.26),以一种可以使用明确规则验证的方式 分配(§16(明确分配))。

        因为它是在 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"
        

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

        【讨论】:

          猜你喜欢
          • 2022-01-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-08-16
          • 1970-01-01
          • 1970-01-01
          • 2016-02-24
          • 1970-01-01
          相关资源
          最近更新 更多