Constructors (Java)
Some authors treat the term default constructor
equal to parameterless constructor
.
In the following text, I understand the default constructor as described by the Java SE 21 language specification1 as the implicit default constructor provided by the compiler if no explicit constructor was declared:
In the absence of explicit constructors, however, the compiler provides a public, parameterless default constructor. To a user, this constructor is indistinguishable from any other. [📖Blo18, p. 19]
Ullenboom refers to an implicit and explicit default constructor, whereas the implicit is provided by the compiler, and the explicit is a parameterless constructor provided by the developer (see [📖Ull18, pp. 515-17]). Ullenboom notes that is is important to understand the author's intend when one simply speaks of default constructor without differentiating between implicit and explicit.
Default Constructor
If a Java class contains no constructor, a default constructor is implicitly declared2.
The default constructor signature's formal parameter list is empty.
class A {
// implicitly declared default constructor
// public A() {
// }
}
A a = new A(); // calls the implicitly declared default constructor
If an explicitly declared constructor is declared, no default constructor will be made available by the compiler.
In the following example, new A()
yields a compiler error, since no parameterless constructor is explicitly or implicitly
declared for A
.
class A {
int a;
// explicitly declared default constructor
// will prevent the implicitly declared default constructor
public A(int value) {
a = value;
}
}
A a1 = new A(i); // calls the explicitly declared default constructor
A a2 = new A(); // yields a compiler error
Inheritance
If a constructor does not have an explicit call to a parent's constructor, it will implicitly call super()
.
If in such cases a parent's class does not have a parameterless constructor declared, a compiler error will be produced.
In the following example, class B
extends A
and has a constructor declared. Its formal parameter list
is int
. This constructor will implicitly call super()
.
class A {
}
class B extends A {
int val;
public B (int a) {
// implicitly called:
// super();
val = a;
}
}
B b = new B(1);
Since each class in Java is a direct or indirect descendant of java.lang.Object
3,
there is also an implicit call to the java.lang.Object
's constructor in A
In the next example, C
extends the above class B
. A default constructor will implicitly be declared for C
. Instantiating
C
will yield a compiler error, since there is no parameterless constructor declared for B
:
class C extends B {
}
C c = new C();
C
requires a constructor with an explicit call to the parent's constructor that should be invoked:
class C extends B {
public C() {
super(2);
}
}
C c = new C();
In Java, the first call of a constructor must always be a call to the parent's constructor. If there is no such explicit call, an implicit call to the parent's parameterless constructor is made4.
Example
class A {
// implicit default constructor: available
// implicit default constructor: calls java.lang.Object's constructor
}
class B extends A {
// implicit default constructor: available
// implicit default constructor: calls A's constructor
}
class C {
// implicit default constructor: not available
public C() {
// implicit call to java.lang.Object's constructor
System.out.println("C created.");
}
}
class D extends C {
// implicit default constructor: available
// implicit default constructor: calls C's constructor
}
class E extends D {
// implicit default constructor: not available
public E() {
// implicit call to D's constructor
System.out.println("E created.");
}
}
class F extends E {
// implicit default constructor: not available
public F(int x) {
// implicit call to E's constructor
System.out.println("F created");
}
}
class G extends F {
// implicit default constructor: not available
public G(int x) {
super(x); // explicit call to F's constructor
// commenting the above statement will implicitly call 'super()', which yields an error.
// -> since there is no default constructor available in F, we **must** tell this constructor which parent's
// constructor is to be called.
System.out.println("G created");
}
}
Constructor Inheritance
In Java, constructors are not members of a class. As such, constructors are not inherited by subclasses5.
- The Java Language Specification (Oracle): https://docs.oracle.com/javase/specs/jls/se21/html/index.html (retrieved 20 October 2023)↩
- "8.8.9. Default Constructor", The Java Language Specification (Oracle): https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.8.9 (retrieved 20 October 2023)↩
- "Object as a Superclass", The Java Tutorials (Oracle): https://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html (retrieved 20 October 2023)↩
- "8.8.7. Constructor Body", The Java Language Specification (Oracle): https://docs.oracle.com/javase/specs/jls/se21/html/jls-8.html#jls-8.8.7 (retrieved 20 October 2023)↩
- "Inheritance", The Java Tutorials (Oracle): https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html (retrieved 20 October 2023)↩