According to the Java tutorial on constructors:
You don\'t have to provide any constructors for your class, but you must be careful when doing this.
The default constructor is defined by the compiler when you don't provide one.
So this
public class A{}
Would be represented by the compiler somewhat as:
public class A
public A() {
super(); //invokes Object's default constructor
}
}
Since my definition of A
did not have an explicit constructor defined.
In the example above A
extends Object
implicitly and Object's
default constructor is automatically invoked by the compiler when it does super()
. The same is true for any classes that may extend A
, for example:
public class B extends A {}
would be implemented by the compiler somewhat like:
public class B extends A {
public B() {
super(); //invokes A's default constructor
}
}
Which as you can see will end up chaining Object
's default constructor, then A
's default constructor and finally B
's default constructor.
> So when will the superclass not have a no-argument constructor?
It won't have a no-arg constructor when you define one explicitly. For example, if I changed my definition of A
to
public class A {
public A(String name){}
}
Then A
no longer has a default constructor and I can no longer do this
public class B extends A {
//Uh oh, compiler error.
//Which parent class constructor should the compiler call?
}
Now B
must explicitly chain the right constructor from its parent class by explicitly stating which one to use. For example
public class B extends A {
B() {
super("B"); //Now the compiler knows which constructor to invoke
}
}
Java Decompiler Demonstration
You can in fact demonstrate all of this by using a tool that comes with your JDK. There is a program in your JDK bin directory called javap
. This is the Java Decompiler tool, which lets you take a look at code generated by the compiler.
You could compile my examples and then decompile them to look at the generated code, e.g.
javac A.java
javap A
And the decompiler will show you:
public class A {
A();
}
Which clearly shows the compiler added a default constructor.
You may disassemble the class to see the byte codes.
javac B.java
javap -c B
And it will show how it invokes the parent class default constructor
class B extends A {
B();
Code:
0: aload_0
1: invokespecial #1 // Method A."":()V
4: return
}
If I add a default parameter to the A
's constructor, you will see the compiler no longer provides the default constructor, it just provides the one I defined explicitly:
class A {
A(String name){}
}
Then I can do
javac A.java
javap A
And it yields
class A {
A(java.lang.String);
}
Which demonstrates that what you read in the specification you cited in the original question is true.