默认构造函数不初始化类的实例成员?

2022-09-03 13:19:12

我遇到了一个问题,询问“关于”默认“构造函数,以下哪项是正确的?

选项“它初始化类的实例成员”是不正确的选择。

现在我的理解是,如果我们有一个这样的代码,

    Class Test {
        String name;
    }

然后编译器创建默认构造函数,如下所示

    Class Test {
        String name;
        Test(){
            super();
            name = null;
        }
    }

初始化实例成员名称的默认构造函数不是空吗?


答案 1

类构造函数不是执行初始化的构造函数,JVM 执行该操作

分配对象的内存后,对象的成员默认初始化为某个可预测值,该值将成为其默认值。这一切都是在调用构造函数之前完成的!

根据规格

  • 每个类变量、实例变量或数组组件在创建时都使用默认值进行初始化 (§15.9§15.10.2):
  • 对于 byte 类型,默认值为零,即 的值。(byte)0
  • 对于 short 类型,默认值为零,即 的值。(short)0
  • 对于 int 类型,缺省值为零,即 。0
  • 对于 long 类型,默认值为零,即 。0L
  • 对于 float 类型,默认值为正零,即 。0.0f
  • 对于 double 类型,缺省值为正零,即 。0.0d
  • 对于 char 类型,缺省值为空字符,即 。'\u0000'
  • 对于布尔类型,缺省值为 。false
  • 对于所有参考类型 (§4.3),缺省值为 。null

您的假设很接近,但事实是,在计算构造函数参数之前,甚至在它为每个字段分配值之前 - 这些字段已经保留了它们的默认值,这是由JVM完成的。

阅读小节 §15.9.4 了解如何执行初始化过程


答案 2

在 Java 中,字段在构造函数之前初始化。这可以通过以下代码轻松证明:

public class MyClass {

    int myField = initMyField();

    MyClass(){
        System.out.println("ctor");
    }

    static int initMyField() {
        System.out.println("init field");
        return 1;
    }
}

输出

init field
ctor

您还可以检查已解编译的代码。