1

为什么没有将默认值分配给尚未在具有主函数的类中初始化的变量???

class Test {
    public static void main(String[] args) {

        int x;// x has no default value
        String y;// y has no default value
        System.out.println("x is " + );
        System.out.println("y is " + );
    }
}

而在没有任何主函数的类中变量保持未初始化的情况下,会分配默认值。

class Student {
    String name; // name has default value null
    int age; // age has default value 0
    boolean isScienceMajor; // isScienceMajor has default value false
    char gender; // c has default value '\u0000'
    int x;
    String y;
}
4

4 回答 4

5

请注意,问题中的代码代表不同的情况。在第一种情况下,变量是局部的并且存在于main()方法内部。在第二种情况下,您声明的是实例属性,而不是局部变量。

在 Java 中,只有属性会使用默认值自动初始化。在所有方法中,甚至在main()方法中,都必须显式地为方法内部声明的变量提供初始化值。

Java 语言规范第4.12.5节对此进行了解释:

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

每个方法参数(第 8.4.1 节)都初始化为方法调用者提供的相应参数值(第 15.12 节)

每个构造函数参数(第 8.8.1 节)都初始化为类实例创建表达式(第 15.9 节)或显式构造函数调用(第 8.8.7 节)提供的相应参数值

异常参数(第 14.20 节)被初始化为表示异常的抛出对象(第 11.3 节、第 14.18 节)

局部变量(第 14.4 节、第 14.14 节)必须在使用之前通过初始化(第 14.4 节)或赋值(第 15.26 节)显式赋予一个值,其方式可以使用明确赋值规则(第16)

要查看局部变量未自动初始化的几个原因请查看此上一个问题

于 2013-07-25T13:51:21.517 回答
2

基本原因是,为了捕捉一个常见的程序员错误,Java 作者决定确保在使用每个变量之前对其进行赋值。但是,不可能对字段强制执行此操作,因此他们必须为字段指定默认值。

如果在初始化之前在构造函数中使用字段,则会出现错误,但编译器无法阻止这种情况:

class C {
  int f;

  C() {
    init();
  }

  void init() {
    System.out.println(f);
  }
}
于 2013-07-25T13:55:06.430 回答
1

在变量被赋值之前读取它的值是常见的错误来源。强制你在使用变量之前赋值可以让程序更安全:你会知道你会得到你期望的值而不是一些默认值,因为你没有预料到某个程序流程。

不幸的是,实现这一点的活性分析只能针对局部变量进行,并且您可以在程序使用值初始化它们之前访问实例字段。为了避免不可预知的行为,JVM 将实例字段初始化为默认值。

于 2013-07-25T13:56:02.527 回答
1

当 JVM 创建新对象实例时,它必须为属性分配内存,因为它们是类本身的一部分。仅存在 Java 原始 int 就需要分配 4 个字节的内存,而 anInteger可以设置为,null因为它是一个对象。这就是为什么类必须在初始化时将其属性设置为某些东西。

于 2013-07-25T13:56:18.913 回答