为什么指示行上面的行没有编译错误?

问题描述 投票:0回答:3

我正在阅读有关 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
    }
}
java variables scope
3个回答
9
投票

相关规则在 JLS § 4.12.5 变量初始值中描述(强调我的):

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

因此,虽然实例变量(例如

a
)会自动获得默认值,但局部变量(例如
b
)不会获得默认值,并且不得使用,除非编译器可以验证是否已为其分配了值.


8
投票

b
是仅在方法作用域中定义的变量,因此编译器可以知道之前没有人初始化过它,但
a
是一个公共变量,可能会在其他地方初始化。


0
投票

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

静态类成员:在类加载时获得初始化(大多数时候,在之前

main()
,但这取决于类加载的时间)。

class S {
  static int a;
}

非静态类成员:当对象存在时被初始化。 (大多数时候在

new
之后,但还有其他更高级的方法来新建对象)。

class S {
  int a;
}

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

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

已更正后编辑...

© www.soinside.com 2019 - 2024. All rights reserved.