简体   繁体   中英

How exactly does the 'new' keyword and constructors work

Ok, so i'm study for my first java certification and i can't quite understand exactly what happens underneath the hood when an object is created, some explanations that iv'e read states that the constructor returns the reference to an object which is a source of confusion for me because from my understanding this is done by the new keyword. My questions are:

  1. Where does the reference to an object actually come from, the 'new' keyword or the constructor?
  2. When an object is created using the 'new' keyword, does it implicitly pass this object to the constructor?
  3. When an object is created using the 'new' keyword, is it just a java Object until it is passed to the constructor eg. Person me = new Person(); Is this object associated with the class person as soon as it is created, or only after it has been passed to the constructor
  1. The entire expression of new Constructor(arguments) is considered one instance-creation expression, and is not meaningful as a separate new keyword and constructor call.

    The JLS, 15.9.4 describes the actual creation of the instance, which is comprised of three steps:

    1. Qualifying the expression (not applicable when using new )
    2. Allocating space for the instance in memory, and setting fields to default values.
    3. Evaluating arguments for the constructor, and calling the constructor.

    First, if the class instance creation expression is a qualified class instance creation expression, the qualifying primary expression is evaluated. If the qualifying expression evaluates to null, a NullPointerException is raised, and the class instance creation expression completes abruptly. If the qualifying expression completes abruptly, the class instance creation expression completes abruptly for the same reason.

    Next, space is allocated for the new class instance. If there is insufficient space to allocate the object, evaluation of the class instance creation expression completes abruptly by throwing an OutOfMemoryError.

    The new object contains new instances of all the fields declared in the specified class type and all its superclasses. As each new field instance is created, it is initialized to its default value (§4.12.5).

    Next, the actual arguments to the constructor are evaluated, left-to-right. If any of the argument evaluations completes abruptly, any argument expressions to its right are not evaluated, and the class instance creation expression completes abruptly for the same reason.

    Next, the selected constructor of the specified class type is invoked. This results in invoking at least one constructor for each superclass of the class type. This process can be directed by explicit constructor invocation statements (§8.8) and is specified in detail in §12.5.

    The value of a class instance creation expression is a reference to the newly created object of the specified class. Every time the expression is evaluated, a fresh object is created.

  2. Yes, as bytecode this all turns into one invokespecial call with the new instance at the bottom of the stack of parameters passed. Please see the bottom of this answer. Semantically, however, the constructor doesn't get the new instance "passed" to it, but that instance is made available as this in Java source code.

  3. This question doesn't make semantic sense, as the object doesn't "exist" to the outside world until the constructor returns. If the construction terminates abruptly, the object is not actually created and available. However , in memory on an OpenJDK JVM at least, the type of the object as well as any types that it extends/implements are written to an in-memory header. This is not guaranteed for all implementations, however.

Disassembly:

I compiled and disassembled:

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

This is the result:

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

As you can see, first the object is allocated using new , which fills in all fields as defaults. It's duplicated, so the stack looks like:

our new Integer
our new Integer

The constant value that I passed to the constructor is then pushed:

2
our new Integer
our new Integer

invokespecial occurs, which passes the top two stack elements--the new instance, and the constructor's parameter.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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