【问题标题】:Why is there no compilation error on the line above the indicated line?为什么指示行上方的行没有编译错误?
【发布时间】:2011-08-02 09:23:50
【问题描述】:

我正在阅读有关 Java 的内容,但我对为什么 System.out.println("a: " + a); 不会产生编译错误感到头疼。 a 曾经在哪里初始化过?

public class localVariableEx {
    public static int a;
    public static void main(String[] args) {
        int b;
        System.out.println("a: " + a);
        System.out.println("b: " + b);  //Compilation error
    }
}

【问题讨论】:

  • b,默认初始化为0(如果未初始化),因为int是原始类型。所以它不能是一个编译错误,而是一个警告你的变量被统一化了。
  • @精英绅士,所以如果初始化为默认值,为什么会出现编译错误?
  • @精英绅士:抱歉,你错了:局部变量不会自动初始化。如果您在尚未确定为它们分配值时尝试访问它们,那么您将收到编译错误。
  • 我的立场是正确的,我之前所说的不适用于局部变量。

标签: java variables compiler-construction scope


【解决方案1】:

b 是只在方法范围内定义的变量,因此编译器可以知道之前没有人对其进行过初始化,但a 是一个可能在其他地方初始化的公共变量。

【讨论】:

  • Tyler:据我所知,这不是正确的答案。请参阅下面的答案。
  • @Asaf,我很确定这是正确的。停止“纠错”。
  • @Tyler: a 初始化 - 当对象被初始化时(使用默认值)。我是来学习的,而不仅仅是回答。 Joachim 确实教会了我一些新东西。
【解决方案2】:

a 是基本类型int,它将立即被初始化,这意味着:

静态类成员:在加载类时初始化(大部分时间是在main() 之前,但这取决于加载类的时间)。

class S {
  static int a;
}

非静态类成员:在对象存在时被初始化。 (大部分时间在new 之后,但还有其他更高级的方法来新建对象)。

class S {
  int a;
}

局部变量:在首次使用前应在方法的范围内初始化。

class S {
  void foo() {
    int b = 0;
  }
}

修正后编辑...

【讨论】:

  • 这段代码不是我写的,它来自我正在阅读的一个网站。我不确定您为什么解释了不同类型的变量,但感谢您的回答。
  • 这是错误的。局部变量不会自动初始化!除非您为它们分配值,否则它们没有值,编译器将不允许您从中读取。
【解决方案3】:

这方面的相关规则在the JLS § 4.12.5 Initial Values of Variables(强调我的)中有描述:

  • 每个类变量实例变量数组组件在创建时都会使用默认值进行初始化(§15.9、@ 987654323@): [...]
  • [...]
  • 局部变量§14.4§14.14必须在使用前显式赋予值,通过初始化(§14.4)或赋值(§15.26),编译器可以使用明确赋值规则 (§16) 进行验证。

因此,虽然实例变量(例如a)自动获得默认值,但局部变量(例如b)不会获得并且不得使用,除非编译器可以验证已分配值给他们。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 2016-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多