当我们创建一个对象时,是否创建了对象并且同时执行了构造函数的执行?

时间:2015-01-14 16:04:15

标签: java constructor

当我们创建一个对象时,是否创建了对象并且构造函数的执行同时发生或者第一个对象被创建然后构造函数执行?

用Herbert Schildt编写:"一旦定义,构造函数会在创建对象后立即自动调用,然后 new 操作符完成&#34 ;。我的队列是,如果new运算符还没有完成它的内存分配,那么在new完成之前如何调用构造函数,因为只有在创建对象之后才调用它的编写构造函数。

3 个答案:

答案 0 :(得分:3)

Section 12.5 of the JLS提供详细信息。它的骨架是:

  • 分配内存空间(所有字段都具有相关类型的默认值,例如null或0)
  • 调用指定类的构造函数,它将立即链接到同一个类中的另一个构造函数或超构造函数
  • 最终链条达到java.lang.Object
  • 在每个返回的构造函数链中,实例变量根据它们的字段初始值设定项进行初始化(如果有的话)(并且只有当我们没有链接到同一个类中的另一个构造函数时),然后执行构造函数体代码。然后返回调用构造函数等。

当然,JLS会更详细,包括内存不足或构造函数体引发异常的情况。

构造函数的每个位的时序很重要:

  • 链接到此/超级构造函数
  • (隐式)如果链是超类构造函数
  • ,则将初始值分配给字段
  • 构造函数主体

重要的是要理解,如果超级构造函数调用了一个显示字段值的重写方法,那么还会通过字段初始化程序。因此,您可以看到字段的默认值,而不是初始化程序所期望的值。例如:

class Bar extends Foo {
    private String name = "fred";

    @Override public String toString() {
        return name;
    }
}

如果Foo构造函数调用toString(),那将null而不是"fred"

(如果namefinal,则在toString()中将其视为常量,其他事情也会发生,但这是另一回事。)

答案 1 :(得分:1)

new运算符通过按顺序执行一些操作来创建一个新对象:它根据需要为对象分配内存(此操作可能会触发JVM中的其他操作),它执行构造函数中定义的代码被调用,最后,它返回到调用者,引用新创建的对象。值得注意的是,构造函数调用在所有变量在当前类中默认初始化之后发生,并且这个相同的序列从层次结构中最顶层的类发生到当前类(因此首先执行Object()等)。

技术上,构造函数在新创建的对象上执行,即为其分配的内存空间,它永远不会在尚未分配或正在分配的内存上执行。

答案 2 :(得分:0)

当您调用new时,会在堆上为对象分配内存,包括将其初始化为默认值的变量。如果值作为构造函数参数提供,则使用这些值。

构造函数完成初始化后,将在堆栈上创建分配给它的变量,并将堆中对象的地址作为其值。

我建议您观看this Stanford lecture,其中详细解释了这一点,以便任何人都能理解。