A new class instance is explicitly created when one of the following situations occurs:
newInstance
method (§20.3.6) of class Class
creates a new instance of the class represented by the Class
object for which the method was invoked.
A new class instance may be implicitly created in the following situations:
String
literal (§3.10.5) may create a new String
object (§20.12) to represent that literal. (This might not occur if the same String
has previously been interned (§3.10.5).)
String
object to represent the result. String concatenation operators may also create temporary wrapper objects for a value of a primitive type.
Each of these situations identifies a particular constructor to be called with specified arguments (possibly none) as part of the class instance creation process.
Whenever a new class instance is created, memory space is allocated for it with room for all the instance variables declared in the class type and all the instance variables declared in each superclass of the class type, including all the instance variables that may be hidden. If there is not sufficient space available to allocate memory for the object, then creation of the class instance completes abruptly with an OutOfMemoryError
. Otherwise, all the instance variables in the new object, including those declared in superclasses, are initialized to their default values (§4.5.4). Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:
this
), then evaluate the arguments and process that constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason; otherwise, continue with step 5.
this
). If this constructor is for a class other than Object
, then this constructor will begin with a explicit or implicit invocation of a superclass constructor (using super
). Evaluate the arguments and process that superclass constructor invocation recursively using these same five steps. If that constructor invocation completes abruptly, then this procedure completes abruptly for the same reason. Otherwise, continue with step 4.
class Point { int x, y; Point() { x = 1; y = 1; } } class ColoredPoint extends Point { int color = 0xFF00FF; } class Test { public static void main(String[] args) { ColoredPoint cp = new ColoredPoint(); System.out.println(cp.color); } }
a new instance of ColoredPoint
is created. First, space is allocated for the new
ColoredPoint
, to hold the fields x
, y
, and color
. All these fields are then initialized to their default values (in this case, 0
for each field). Next, the ColoredPoint
constructor with no arguments is first invoked. Since ColoredPoint
declares no
constructors, a default constructor of the form:
ColoredPoint() { super(); }
is provided for it automatically by the Java compiler.
This constructor then invokes the Point
constructor with no arguments. The Point
constructor does not begin with an invocation of a constructor, so the compiler provides an implicit invocation of its superclass constructor of no arguments, as though it had been written:
Point() { super(); x = 1; y = 1; }
Therefore, the constructor for Object
which takes no arguments is invoked.
The class Object
has no superclass, so the recursion terminates here. Next, any instance variable initializers and static initializers of Object
are invoked. Next, the body of the constructor of Object
that takes no arguments is executed. No such constructor is declared in Object
, so the compiler supplies a default one, which in this special case is:
Object() { }
This constructor executes without effect and returns.
Next, all initializers for the instance variables of class Point
are executed. As it happens, the declarations of x
and y
do not provide any initialization expressions, so no action is required for this step of the example. Then the body of the Point
constructor is executed, setting x
to 1
and y
to 1
.
Next, the initializers for the instance variables of class ColoredPoint
are executed. This step assigns the value 0xFF00FF
to color
. Finally, the rest of the body of the ColoredPoint
constructor is executed (the part after the invocation of super
); there happen to be no statements in the rest of the body, so no further action is required and initialization is complete.
Unlike C++, the Java language does not specify altered rules for method dispatch during the creation of a new class instance. If methods are invoked that are overridden in subclasses in the object being initialized, then these overriding methods are used, even before the new object is completely initialized. Thus, compiling and running the example:
class Super { Super() { printThree(); } void printThree() { System.out.println("three"); } }
class Test extends Super { int indiana = (int)Math.PI; // That is, 3 public static void main(String[] args) { Test t = new Test(); t.printThree(); } void printThree() { System.out.println(indiana); } }
0
3
This shows that the invocation of printThree
in the constructor for class Super
does not invoke the definition of printThree
in class Super
, but rather invokes
the overriding definition of printThree
in class Test
. This method therefore
runs before the field initializers of Test
have been executed, which is why the first
value output is 0
, the default value to which the field three
of Test
is initialized.
The later invocation of printThree
in method main
invokes the same definition
of printThree
, but by that point the initializer for instance variable three
has
been executed, and so the value 3
is printed.
See §8.6 for more details on constructor declarations.