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.
如果你有一个没有显式默认构造函数的超类A,
子类B扩展A,没有明确的默认构造函数,
并且在驱动程序类的主要方法中
一个obj1 = new A();
将创建一个默认构造函数,它将调用Object类的默认构造函数,对吗?
但如果你这样做
B obj2 = new B();
根据教程,将生成B的默认构造函数,构造函数将调用超类的无参构造函数,后者将依次调用Object中的构造函数.
那么什么时候超类没有无参数构造函数呢?
解决方法:
默认构造函数由编译器在您未提供时定义.
所以这
public class A{}
将在某种程度上由编译器表示为:
public class A
public A() {
super(); //invokes Object's default constructor
}
}
由于我对A的定义没有定义明确的构造函数.
在上面的示例中,A隐式地扩展了Object,并且当它执行super()时,编译器会自动调用Object的默认构造函数.任何可能扩展A的类都是如此,例如:
public class B extends A {}
将由编译器实现有点像:
public class B extends A {
public B() {
super(); //invokes A's default constructor
}
}
你可以看到最终将链接Object的默认构造函数,然后是A的默认构造函数,最后是B的默认构造函数.
>那么什么时候超类没有无参数构造函数呢?
当您明确定义一个时,它将没有no-arg构造函数.例如,如果我将A的定义更改为
public class A {
public A(String name){}
}
然后A不再有默认构造函数,我不能再这样做了
public class B extends A {
//Uh oh, compiler error.
//Which parent class constructor should the compiler call?
}
现在B必须通过明确说明要使用哪一个来明确地从其父类链接正确的构造函数.例如
public class B extends A {
B() {
super("B"); //Now the compiler knows which constructor to invoke
}
}
Java反编译器演示
事实上,您可以使用JDK附带的工具来演示所有这些. JDK bin目录中有一个名为javap的程序.这是Java Decompiler工具,它允许您查看编译器生成的代码.
您可以编译我的示例然后反编译它们以查看生成的代码,例如
javac A.java
javap A
反编译器会告诉你:
public class A {
A();
}
这清楚地表明编译器添加了一个默认构造函数.
您可以反汇编类以查看字节代码.
javac B.java
javap -c B
它将显示它如何调用父类的默认构造函数
class B extends A {
B();
Code:
0: aload_0
1: invokespecial #1 // Method A."":()V
4: return
}
如果我向A的构造函数添加一个默认参数,您将看到编译器不再提供默认构造函数,它只提供我明确定义的那个:
class A {
A(String name){}
}
然后我就能做到
javac A.java
javap A
它产生了
class A {
A(java.lang.String);
}
这表明您在原始问题中引用的规范中所读到的内容是正确的.
标签:java,class,constructor,inheritance
来源: https://codeday.me/bug/20190823/1697920.html