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.
And in the
main
method of a driver class you doA obj1 = new A();
a default constructor will be created
There is nothing you can do in the main
method of a driver to create a default constructor. If it is defined, you can use it; if it is not defined, you get a compile error.
So when will the superclass not have a no-argument constructor?
When it has other constructors, all of which taking some arguments. Here is an example:
class SuperA {
public SuperA(String str) { ... }
public SuperA(int num) { ... }
}
Above, SuperA
has two constructors - one taking a String
, and another one taking an int
. Neither of them is default, because they take parameters.
If you make a derived class DerivedB extends SuperA
and do not define any constructors, you would get a compile error.
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.
So when will the superclass not have a no-argument constructor?
If you add any other constructor of superclass but forget to add no-arg constructor the compiler will complain. In this case the default constructor of superclass is not provided.