Search code examples
javaconstructorinstance-variables

How is it possible for variables to be initialized outside of the constructor?


Variables only get memory allocation during object creation, so why does assigning a value to a variable outside a constructor produce no error? Moreover what is the location of this assigned value as no particular object is created?


Solution

  • Because all of the instance field initializer code (and any instance initializer blocks) are executed as if they were part of the constructor.

    Variables only get memory allocation during object creation

    In fact, the sequence is as follows:

    1. Evaluate constructor argument expressions.
    2. Perform class initialization if it hasn't already been performed. (This happens once in the lifetime of the class ...)
    3. Allocate the memory for the object, including the memory for the instance fields of the class and superclass chain.
    4. Perform default initialization the fields.
    5. Perform the this(...) or super(...) call. (This recurses up the chain performing field initialization and running constructors. For a this call, we then skip the next step.)
    6. Execute the classes instance field initializers and static initializer blocks, in source code order.
    7. Execute the remainder of the constructor.
    8. If this was the leaf constructor, return the constructed object. Otherwise unwind one level of recursion.

    Step 6 is where the field initializers you were concerned about get dealt with. The code for the initializer expressions and blocks are combined into a synthetic method that gets called by the constructor at the appropriate point. However, that is an implementation detail.

    As you can see, the amount of memory allocated to the object is determined very early on, and is not affected by any of the initialization logic. The variables and the amount of memory needed to represent them in the object itself will be the same ... no matter what.

    Moreover what is the location of this assigned value as no particular object is created?

    The locations of the fields are part of the object allocated in step 3. Just like the case where the initialization was done in the constructor.

    (Perhaps you were confused about what actually happens when you assign an object or array to a field? Remember that Object and Array types are called reference types. A field or variable whose type is a reference type corresponds to a location to hold just the reference ... NOT the actual state of the object that the reference refers to.)

    (Perhaps you were thinking that the invocation of a constructor is the same as the invocation of a normal method. That isn't so ... see above.)