Java默认值混淆,为什么没有函数作用域变量?

我对于我认为不一致的原因感到困惑。

例如

public class Test { static int a; public static void main(String[] args) { System.out.println(a); } } 

因此,将按预期打印0。 但是说我们有这个,

 public class Test { public static void main(String[] args) { int a; System.out.println(a); } } 

这不会为我编译,抱怨a尚未初始化。 我期待它打印0 …

这引出了一些问题:

1)为什么函数范围变量没有默认值?

2)静态关键字可能是原因吗? 为什么?

Java语言规范解释了变量的默认初始值

每个类变量,实例变量或数组组件在创建时都使用默认值进行初始化(§15.9,§15.10):

对于type字节,默认值为零,即(byte)0的值。

对于short类型,默认值为零,即(short)0的值。

对于int类型,默认值为零,即0。

对于long类型,默认值为零,即0L。

对于float类型,默认值为正零,即0.0f。

对于double类型,默认值为正零,即0.0d。

对于char类型,默认值为空字符,即’\ u0000’。

对于boolean类型,默认值为false。

对于所有引用类型(第4.3节),默认值为null。

并且还说明

局部变量(§14.4,§14.14)必须在使用之前通过初始化(§14.4)或赋值(§15.26)显式给出一个值,其方式可以使用明确赋值的规则进行validation(§ 16)。

您的问题都可以通过“因为JLS这么说”来回答。

更完整的答案如下:

类是对状态和行为的描述。 对象是实际数据。 如果创建对象,它必须具有明确的状态,它不能处于未初始化状态。

1)为什么函数范围变量没有默认值?

JLS定义的规则是方法变量不会初始化为默认值。 您需要在使用前初始化它们

2)静态关键字可能是原因吗? 为什么?

再次形成JLS规则,类实例变量由编译器初始化为默认值。 您可能会也可能不会初始化它们。

Java编译器从不为Local变量分配默认值,如链接http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html中所述。

您必须显式初始化它们。