[英]How exactly does the 'new' keyword and constructors work
好的,所以我正在研究我的第一个Java认证,而且我还不太了解在创建对象时引擎盖下到底发生了什么,一些读过的解释指出,构造函数将引用返回给对象,即这让我感到困惑,因为根据我的理解,这是由new关键字完成的。 我的问题是:
new Constructor(arguments)
的整个表达式被视为一个实例创建表达式,作为单独的new
关键字和构造函数调用没有意义。
JLS 15.9.4描述了实例的实际创建,包括三个步骤:
new
时不适用) 首先,如果类实例创建表达式是合格的类实例创建表达式,则对合格的主表达式进行求值。 如果限定表达式的结果为null,则引发NullPointerException,并且类实例创建表达式突然完成。 如果限定表达式突然完成,则类实例创建表达式由于相同的原因突然完成。
接下来,为新的类实例分配空间。 如果没有足够的空间来分配对象,则通过抛出OutOfMemoryError突然完成对类实例创建表达式的评估。
新对象包含在指定类类型及其所有超类中声明的所有字段的新实例。 创建每个新的字段实例时,会将其初始化为其默认值(第4.12.5节)。
接下来,从左到右评估构造函数的实际参数。 如果任何一个参数求值突然完成,则不会评估其右边的任何参数表达式,并且出于相同的原因,类实例创建表达式也会突然完成。
接下来,将调用指定类类型的选定构造函数。 这导致为类类型的每个超类调用至少一个构造函数。 此过程可以由显式构造函数调用语句(第8.8节)指导,并在第12.5节中详细指定。
类实例创建表达式的值是对指定类的新创建对象的引用。 每次对表达式求值时,都会创建一个新对象。
是的,因为字节码全部变为一个invokespecial调用,新实例位于传递的参数堆栈的底部。 请参阅此答案的底部。 语义,但是,构造并没有得到新的实例“传递”给它,但该实例提供的this
Java源代码。
我编译并反汇编:
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.