Constructor Declarations

8.8 Constructor Declarations

A constructor is used in the creation of an object that is an instance of a class (§12.5, §15.9).

ConstructorDeclaration: ConstructorModifiers opt ConstructorDeclarator

opt ConstructorBody Throws

ConstructorDeclarator: TypeParameters opt SimpleTypeName ( FormalParameterList opt )

The SimpleTypeName in the ConstructorDeclarator must be the simple name of the class that contains the constructor declaration; otherwise a compile-time error occurs.

In all other respects, the constructor declaration looks just like a method declaration that has no result type.

CLASSES Formal Parameters and Type Parameters 8.8.1

Constructor declarations are not members. They are never inherited and therefore are not subject to hiding or overriding.

Example 8.8-1. Constructor Declarations

class Point { int x, y; Point(int x, int y) { this.x = x; this.y = y; }

Constructors are invoked by class instance creation expressions (§15.9), by the conversions and concatenations caused by the string concatenation operator + (§15.18.1), and by explicit constructor invocations from other constructors (§8.8.7).

Constructors are never invoked by method invocation expressions (§15.12). Access to constructors is governed by access modifiers (§6.6).

This is useful, for example, in preventing instantiation by declaring an inaccessible constructor (§8.8.10).

8.8.1 Formal Parameters and Type Parameters

The formal parameters and type parameters of a constructor are identical in syntax and semantics to those of a method (§8.4.1).

8.8.2 Constructor Signature

It is a compile-time error to declare two constructors with override-equivalent signatures (§8.4.2) in a class.

It is a compile-time error to declare two constructors whose signatures have the same erasure (§4.6) in a class.

8.8.3 Constructor Modifiers

ConstructorModifiers: ConstructorModifier ConstructorModifiers ConstructorModifier

ConstructorModifier: one of

Annotation public protected private

8.8.3 Constructor Modifiers CLASSES

If an annotation a (§9.7) on a constructor corresponds to an annotation type T (§9.6), and T has a (meta-)annotation m that corresponds to java.lang.annotation.Target , then m must have an element whose value is java.lang.annotation.ElementType.CONSTRUCTOR , or a compile-time error occurs.

The access modifiers public , protected , and private are discussed in §6.6.

It is a compile-time error if the same modifier appears more than once in a constructor declaration, or if a constructor declaration has more than one of the access modifiers public , protected , and private .

It is a compile-time error if the constructor of an enum type (§8.9) is declared public or protected .

If no access modifier is specified for the constructor of a normal class, the constructor has default access.

If no access modifier is specified for the constructor of an enum type, the constructor is private .

If two or more (distinct) method modifiers appear in a method declaration, it is customary, though not required, that they appear in the order consistent with that shown above in the production for MethodModifier.

Unlike methods, a constructor cannot be abstract , static , final , native , strictfp , or synchronized :

• A constructor is not inherited, so there is no need to declare it final . • An abstract constructor could never be implemented. • A constructor is always invoked with respect to an object, so it makes no sense for a

constructor to be static . • There is no practical need for a constructor to be synchronized , because it would lock

the object under construction, which is normally not made available to other threads until all constructors for the object have completed their work.

• The lack of native constructors is an arbitrary language design choice that makes it easy for an implementation of the Java virtual machine to verify that superclass constructors are always properly invoked during object creation.

• The inability to declare a constructor as strictfp (in contrast to a method (§8.4.3)) is an intentional language design choice; it effectively ensures that a constructor is FP- strict if and only if its class is FP-strict (§15.4).

CLASSES Generic Constructors 8.8.4

8.8.4 Generic Constructors

It is possible for a constructor to be declared generic, independently of whether the class the constructor is declared in is itself generic.

A constructor is generic if it declares one or more type variables (§4.4). These type variables are known as the type parameters of the constructor. The

form of the type parameter section of a generic constructor is identical to the type parameter section of a generic class (§8.1.2).

A generic constructor declaration defines a set of constructors, one for each possible invocation of the type parameter section by type arguments. Type arguments may not need to be provided explicitly when a generic constructor is invoked, as they can often by inferred (§15.12.2.7).

The scope and shadowing of a constructor's type parameter is specified in §6.3 and §6.4.

8.8.5 Constructor Throws

The throws clause for a constructor is identical in structure and behavior to the throws clause for a method (§8.4.6).

8.8.6 The Type of a Constructor

The type of a constructor consists of its signature and the exception types given its throws clause.

8.8.7 Constructor Body

The first statement of a constructor body may be an explicit invocation of another constructor of the same class or of the direct superclass (§8.8.7.1).

ConstructorBody: { ExplicitConstructorInvocation opt BlockStatements opt }

It is a compile-time error for a constructor to directly or indirectly invoke itself through a series of one or more explicit constructor invocations involving this .

If the constructor is a constructor for an enum type (§8.9), it is a compile-time error for it to invoke the superclass constructor explicitly.

If a constructor body does not begin with an explicit constructor invocation and the constructor being declared is not part of the primordial class Object , then

8.8.7 Constructor Body CLASSES

the constructor body implicitly begins with a superclass constructor invocation " super(); ", an invocation of the constructor of its direct superclass that takes no arguments.

Except for the possibility of explicit constructor invocations, the body of a constructor is like the body of a method (§8.4.7).

A return statement (§14.17) may be used in the body of a constructor if it does not include an expression.

Example 8.8.7-1. Constructor Bodies

class Point { int x, y; Point(int x, int y) { this.x = x; this.y = y; }

} class ColoredPoint extends Point {

static final int WHITE = 0, BLACK = 1; int color; ColoredPoint(int x, int y) {

this(x, y, WHITE);

} ColoredPoint(int x, int y, int color) {

super(x, y); this.color = color;

Here, the first constructor of ColoredPoint invokes the second, providing an additional argument; the second constructor of ColoredPoint invokes the constructor of its superclass Point , passing along the coordinates.

8.8.7.1 Explicit Constructor Invocations ExplicitConstructorInvocation:

NonWildTypeArguments opt this ( ArgumentList opt ) ; NonWildTypeArguments opt super ( ArgumentList opt ) ; Primary . NonWildTypeArguments opt super ( ArgumentList opt ) ;

NonWildTypeArguments: < ReferenceTypeList >

ReferenceTypeList: ReferenceType ReferenceTypeList , ReferenceType

Explicit constructor invocation statements can be divided into two kinds:

CLASSES Constructor Body 8.8.7

• Alternate constructor invocations begin with the keyword this (possibly prefaced with explicit type arguments). They are used to invoke an alternate constructor of the same class.

• Superclass constructor invocations begin with either the keyword super (possibly prefaced with explicit type arguments) or a Primary expression. They are used to invoke a constructor of the direct superclass.

Superclass constructor invocations may be subdivided: ◆ Unqualified superclass constructor invocations begin with the keyword super

(possibly prefaced with explicit type arguments). ◆ Qualified superclass constructor invocations begin with a Primary expression.

They allow a subclass constructor to explicitly specify the newly created object's immediately enclosing instance with respect to the direct superclass (§8.1.3). This may be necessary when the superclass is an inner class.

An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods or inner classes declared in this class or any superclass, or use this or super in any expression; otherwise, a compile- time error occurs.

The exception types that an explicit constructor invocation statement can throw are specified in §11.2.2.

Example 8.8.7.1-1. Qualified Superclass Constructor Invocation

class Outer { class Inner {} } class ChildOfInner extends Outer.Inner {

ChildOfInner() { (new Outer()).super(); } }

Example 8.8.7.1-2. Restrictions on Explicit Constructor Invocation Statements

If the first constructor of ColoredPoint in the example from §8.8.7 were changed as follows:

class Point { int x, y; Point(int x, int y) { this.x = x; this.y = y; }

} class ColoredPoint extends Point {

static final int WHITE = 0, BLACK = 1; int color; ColoredPoint(int x, int y) {

this(x, y, color); // Changed to color from WHITE

8.8.7 Constructor Body CLASSES

} ColoredPoint(int x, int y, int color) {

super(x, y); this.color = color;

then a compile-time error would occur, because the instance variable color cannot be used by a explicit constructor invocation statement.

Let C be the class being instantiated, and let S be the direct superclass of C . It is a compile-time error if S is not accessible (§6.6). If a superclass constructor invocation statement is qualified, then: • If S is not an inner class, or if the declaration of S occurs in a static context, then

a compile-time error occurs. • Otherwise, let p

be the Primary expression immediately preceding " .super ". Let

be the innermost lexically enclosing class of S . It is a compile-time error if the type of p is not O or a subclass of O , or if the type

of p is not accessible (§6.6). If a superclass constructor invocation statement is unqualified, and if S is an inner

member class, then it is a compile-time error if S is not a member of a lexically

enclosing class of C by declaration or inheritance.

Evaluation of an alternate constructor invocation statement proceeds by first evaluating the arguments to the constructor, left-to-right, as in an ordinary method invocation; and then invoking the constructor.

Evaluation of a superclass constructor invocation statement is more complicated, as follows:

1. Let C be the class being instantiated, let S

be the direct superclass of C , and let

be the instance being created.

2. The immediately enclosing instance of i with respect to S (if any) must be determined:

• If S is not an inner class, or if the declaration of S occurs in a static context, no immediately enclosing instance of i with respect to S exists.

• If the superclass constructor invocation is qualified, then the Primary

expression p immediately preceding " .super " is evaluated.

If p evaluates to null ,a NullPointerException is raised, and the superclass constructor invocation completes abruptly.

CLASSES Constructor Overloading 8.8.8

Otherwise, the result of this evaluation is the immediately enclosing instance of i with respect to S .

• If the superclass constructor invocation is not qualified, then: ◆ If S is a local class (§14.3), then let O be the innermost lexically enclosing

class of S . Let n be an integer such that O is the n'th lexically enclosing

class of C . The immediately enclosing instance of i with respect to S is the n'th

lexically enclosing instance of this . ◆ Otherwise, S is an inner member class (§8.5).

Let O be the innermost lexically enclosing class of S , and let n be an integer such that O is the n'th lexically enclosing class of C .

The immediately enclosing instance of i with respect to S is the n'th lexically enclosing instance of this .

3. After determining the immediately enclosing instance of i with respect to S (if any), evaluation of the superclass constructor invocation statement proceeds by evaluating the arguments to the constructor, left-to-right, as in an ordinary method invocation; and then invoking the constructor.

4. Finally, if the superclass constructor invocation statement completes normally, then all instance variable initializers of C and all instance initializers of C are executed. If an instance initializer or instance variable initializer I textually precedes another instance initializer or instance variable initializer J , then I is executed before J .

Execution of instance variable initializers and instance initializers is performed regardless of whether the superclass constructor invocation actually appears as an explicit constructor invocation statement or is provided automatically. (An alternate constructor invocation does not perform this additional implicit execution.)

8.8.8 Constructor Overloading

Overloading of constructors is identical in behavior to overloading of methods (§8.4.9). The overloading is resolved at compile-time by each class instance creation expression (§15.9).

8.8.9 Default Constructor CLASSES

8.8.9 Default Constructor

If a class contains no constructor declarations, then a default constructor with no formal parameters and no throws clause is implicitly declared.

If the class being declared is the primordial class Object , then the default constructor has an empty body. Otherwise, the default constructor simply invokes the superclass constructor with no arguments.

It is a compile-time error if a default constructor is implicitly declared but the superclass does not have an accessible constructor (§6.6) that takes no arguments and has no throws clause.

In a class type, if the class is declared public , then the default constructor is implicitly given the access modifier public (§6.6); if the class is declared protected , then the default constructor is implicitly given the access modifier protected (§6.6); if the class is declared private , then the default constructor is implicitly given the access modifier private (§6.6); otherwise, the default constructor has the default access implied by no access modifier.

In an enum type, the default constructor is implicitly private (§8.9.2).

Example 8.8.9-1. Default Constructors

The declaration: public class Point {

int x, y; }

is equivalent to the declaration: public class Point {

int x, y; public Point() { super(); }

} where the default constructor is public because the class Point is public .

Example 8.8.9-2. Accessibility of Constructors v. Classes

The rule that the default constructor of a class has the same access modifier as the class itself is simple and intuitive. Note, however, that this does not imply that the constructor is accessible whenever the class is accessible. Consider:

package p1; public class Outer {

CLASSES Preventing Instantiation of a Class 8.8.10

protected class Inner {} } package p2; class SonOfOuter extends p1.Outer {

void foo() { new Inner(); // compile-time access error } }

The constructor for Inner is protected . However, the constructor is protected relative to Inner , while Inner is protected relative to Outer . So, Inner is accessible in SonOfOuter , since it is a subclass of Outer . Inner 's constructor is not accessible in SonOfOuter , because the class SonOfOuter is not a subclass of Inner ! Hence, even though Inner is accessible, its default constructor is not.

8.8.10 Preventing Instantiation of a Class

A class can be designed to prevent code outside the class declaration from creating instances of the class by declaring at least one constructor, to prevent the creation of an implicit constructor, and by declaring all constructors to be private .

A public class can likewise prevent the creation of instances outside its package by declaring at least one constructor, to prevent creation of a default constructor with public access, and by declaring no constructor that is public .

Example 8.8.10-1. Preventing Instantiation via Constructor Accessibility

class ClassOnly { private ClassOnly() { } static String just = "only the lonely";

} Here, the class ClassOnly cannot be instantiated, while in the following code: package just;

public class PackageOnly { PackageOnly() { } String[] justDesserts = { "cheesecake", "ice cream" };

} the class PackageOnly can be instantiated only within the package just , in which it is

declared.