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."<init>":()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.