When do superclasses not have a default constructor?

穿精又带淫゛_ 提交于 2019-12-20 01:16:20

问题


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?


回答1:


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.




回答2:


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.




回答3:


And in the main method of a driver class you do

A 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.



来源:https://stackoverflow.com/questions/48392818/when-do-superclasses-not-have-a-default-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!