Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When do superclasses not have a default constructor?

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 compiler automatically provides a no-argument, default constructor for any class without constructors. This default constructor will call the no-argument constructor of the superclass. In this situation, the compiler will complain if the superclass doesn't have a no-argument constructor so you must verify that it does. If your class has no explicit superclass, then it has an implicit superclass of Object, which does have a no-argument constructor.

If you have a superclass A that has no explicit default constructor,
and a subclass B extends A that has no explicit default constructor,

And in the main method of a driver class you do
A obj1 = new A();
a default constructor will be created,
which will call the default constructor of the Object class, correct?

But if you do
B obj2 = new B();
according to the tutorial, a default constructor for B will be generated,
and the constructor will call the no-argument constructor of the superclass,
which will in turn call the constructor in Object.

So when will the superclass not have a no-argument constructor?

like image 779
rwu6 Avatar asked Jan 23 '18 01:01

rwu6


2 Answers

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.

like image 162
Edwin Dalorzo Avatar answered Sep 21 '22 14:09

Edwin Dalorzo


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.

like image 35
Roman C Avatar answered Sep 20 '22 14:09

Roman C