22 CHAPTER 4. DECLARATIONS
4.1.9 Classifier initialization
When creating a class or object instance via one of its constructors
ctor
, it is
initialized in a particular order, which we describe here.
A primary
pctor
or secondary constructor
ctor
has a corresponding superclass
constructor sctor defined as follows.
•
For primary constructor
pctor
, a corresponding superclass constructor
sctor is the one from the supertype specifier list;
•
For secondary constructor
ctor
, a corresponding supertype constructor
sctor is the one ending the constructor delegation chain of ctor;
•
If an explicit superclass constructor is not available,
Any()
is implicitly
used.
When a classifier type is initialized using a particular secondary constructor
ctor
delegated to primary constructor
pctor
which, in turn, is delegated to
the corresponding superclass constructor
sctor
, the following happens, in this
initialization order :
•
The superclass object is initialized as if created by invoking
sctor
with the
specified parameters;
•
Interface delegation expressions are invoked and the result of each is stored
in the object to allow for interface delegation, in the order of appearance
of delegation declarations in the supertype specifier list;
• pctor
is invoked using the specified parameters, initializing all the properties
declared by its property parameters in the order of appearance in the
constructor declaration;
•
Each property initialization code as well as the initialization blocks in the
class body are invoked in the order of appearance in the class body;
• ctor body is invoked using the specified parameters.
Note: this means that if an
init
-block appears between two property
declarations in the class body, its body is invoked between the
initialization code of these two properties.
The initialization order stays the same if any of the entities involved are omitted,
in which case the corresponding step is also omitted (e.g., if the object is created
using the primary constructor, the body of the secondary one is not invoked).
If any step in the initialization order creates a loop, it results in unspecified
behaviour.
If any of the properties are accessed before they are initialized w.r.t initialization
order (e.g., if a method called in an initialization block accesses a property
declared after the initialization block), the value of the property is unspecified.
It stays unspecified even after the “proper” initialization is performed.
Note: this can also happen if a property is captured in a lambda
expression used in some way during subsequent initialization steps.