超类何时没有默认的构造函数? [英] When do superclasses not have a default constructor?
问题描述
您不必为类提供任何构造函数,但是
在执行此操作时必须小心。编译器会自动为任何没有构造函数的类提供
无参数的默认构造函数。
此默认构造函数将调用
超类的无参数构造函数。在这种情况下,如果
超类没有无参数构造函数,则编译器会抱怨,因此您必须验证
确实具有该参数。如果您的类没有显式超类,则它具有Object的
隐式超类,该类确实具有无参数的
构造函数。
如果您有没有显式默认构造函数的超类 A ,则
和一个子类 B 扩展了一个没有显式默认构造函数的A
If you have a superclass A that has no explicit default constructor,
and a subclass B extends A that has no explicit default constructor,
在驱动程序类的主方法中,您执行
A obj1 = new A();
a将创建默认构造函数,
它将调用对象类,对吗?
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?
但是如果您这样做
B obj2 = new B();
按照教程的
,将生成B的默认构造函数,
,构造函数将调用超类的无参数构造函数,
依次调用该构造函数在对象中。
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?
推荐答案
默认构造函数由编译器定义,当您不提供默认构造函数时。
The default constructor is defined by the compiler when you don't provide one.
因此,
public class A{}
将由编译器表示
public class A
public A() {
super(); //invokes Object's default constructor
}
}
由于我对 A
没有定义显式构造函数。
Since my definition of A
did not have an explicit constructor defined.
在上面的示例中, A
隐式扩展 Object
,而 Object的
默认构造函数在编译器执行<$ c $时会自动调用c> super()。对于任何可能扩展 A
的类也是如此,例如:
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
}
}
如您所见将最终链接 Object
的默认构造函数,然后链接 A
的默认构造函数,最后是 B
的默认构造函数。
Which as you can see will end up chaining Object
's default constructor, then A
's default constructor and finally B
's default constructor.
>那么,超类何时将没有无参数构造函数?
当您明确定义一个时,它将没有no-arg构造函数。例如,如果我将 A
的定义更改为
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){}
}
然后 A
不再具有默认构造函数,我再也不能这样做
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?
}
现在 B
必须通过显式说明要使用的构造函数,从其父类显式链接正确的构造函数。例如
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演示
实际上,您可以使用JDK附带的工具来演示所有这些内容。您的JDK bin目录中有一个名为 javap
的程序。这是Java Decompiler工具,可让您查看由编译器生成的代码。
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
反编译器会向您显示:
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
}
如果我向 A
添加默认参数的构造函数,您将看到编译器不再提供默认的构造函数,而只提供了我明确定义的构造函数:
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){}
}
然后我可以做
javac A.java
javap A
它产生
class A {
A(java.lang.String);
}
这表明您在原始问题中引用的规范中所读内容是是的。
Which demonstrates that what you read in the specification you cited in the original question is true.
这篇关于超类何时没有默认的构造函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!