繁体   English   中英

“ new”关键字和构造函数的工作原理

[英]How exactly does the 'new' keyword and constructors work

好的,所以我正在研究我的第一个Java认证,而且我还不太了解在创建对象时引擎盖下到底发生了什么,一些读过的解释指出,构造函数将引用返回给对象,即这让我感到困惑,因为根据我的理解,这是由new关键字完成的。 我的问题是:

  1. 对对象的引用实际上来自“ new”关键字还是构造函数?
  2. 使用'new'关键字创建对象时,是否将其隐式传递给构造函数?
  3. 当使用'new'关键字创建对象时,它只是一个Java对象,直到将其传递给构造函数为止。 人我= new Person(); 该对象是在创建后立即与类person关联的,还是仅在将其传递给构造函数之后才与它关联的对象
  1. new Constructor(arguments)的整个表达式被视为一个实例创建表达式,作为单独的new关键字和构造函数调用没有意义。

    JLS 15.9.4描述了实例的实际创建,包括三个步骤:

    1. 限定表达式(使用new时不适用)
    2. 在内存中为实例分配空间,并将字段设置为默认值。
    3. 评估构造函数的参数,然后调用构造函数。

    首先,如果类实例创建表达式是合格的类实例创建表达式,则对合格的主表达式进行求值。 如果限定表达式的结果为null,则引发NullPointerException,并且类实例创建表达式突然完成。 如果限定表达式突然完成,则类实例创建表达式由于相同的原因突然完成。

    接下来,为新的类实例分配空间。 如果没有足够的空间来分配对象,则通过抛出OutOfMemoryError突然完成对类实例创建表达式的评估。

    新对象包含在指定类类型及其所有超类中声明的所有字段的新实例。 创建每个新的字段实例时,会将其初始化为其默认值(第4.12.5节)。

    接下来,从左到右评估构造函数的实际参数。 如果任何一个参数求值突然完成,则不会评估其右边的任何参数表达式,并且出于相同的原因,类实例创建表达式也会突然完成。

    接下来,将调用指定类类型的选定构造函数。 这导致为类类型的每个超类调用至少一个构造函数。 此过程可以由显式构造函数调用语句(第8.8节)指导,并在第12.5节中详细指定。

    类实例创建表达式的值是对指定类的新创建对象的引用。 每次对表达式求值时,都会创建一个新对象。

  2. 是的,因为字节码全部变为一个invokespecial调用,新实例位于传递的参数堆栈的底部。 请参阅此答案的底部。 语义,但是,构造并没有得到新的实例“传递”给它,但该实例提供的this Java源代码。

  3. 这个问题在语义上没有意义,因为在构造函数返回之前,对象不会“存在”于外界。 如果构造突然终止,则该对象实际上不会创建并且不可用。 但是 ,至少在OpenJDK JVM的内存中,对象的类型以及它扩展/实现的任何类型都将写入内存标头中。 但是,并非所有实现都可以保证。

拆卸:

我编译并反汇编:

class Test{
    public static void main(String args[]){
        Integer s = new Integer(2);
    }
}

结果如下:

public static void main(java.lang.String[]);
    Code:
       0: new           #2                  // class java/lang/Integer
       3: dup
       4: iconst_2
       5: invokespecial #3                  // Method java/lang/Integer."<init>":(I)V
       8: astore_1
       9: return

如您所见,首先使用new分配对象,该对象将默认填写所有字段。 它是重复的,因此堆栈如下所示:

our new Integer
our new Integer

然后将我传递给构造函数的常量值压入:

2
our new Integer
our new Integer

发生invokespecial ,它传递顶部的两个堆栈元素-新实例和构造函数的参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM