Java 超类何时没有默认构造函数?
根据报告: 您不必为类提供任何构造函数,但是 做这件事时一定要小心。编译器自动提供 没有参数,没有构造函数的任何类的默认构造函数。 此默认构造函数将调用 超类。在这种情况下,如果 超类没有无参数构造函数,因此必须验证 确实如此。如果您的类没有显式超类,那么它有一个 对象的隐式超类,它没有参数 构造函数。 如果您有一个没有显式默认构造函数的超类a,Java 超类何时没有默认构造函数?,java,class,inheritance,constructor,Java,Class,Inheritance,Constructor,根据报告: 您不必为类提供任何构造函数,但是 做这件事时一定要小心。编译器自动提供 没有参数,没有构造函数的任何类的默认构造函数。 此默认构造函数将调用 超类。在这种情况下,如果 超类没有无参数构造函数,因此必须验证 确实如此。如果您的类没有显式超类,那么它有一个 对象的隐式超类,它没有参数 构造函数。 如果您有一个没有显式默认构造函数的超类a, 子类B扩展了一个没有显式默认构造函数的 在驱动程序类的主要方法中,您可以执行 A obj1=新A() 将创建一个默认构造函数,它将调用对象类的默认构造
子类B扩展了一个没有显式默认构造函数的 在驱动程序类的主要方法中,您可以执行
A obj1=新A()代码>
将创建一个默认构造函数,
它将调用对象类的默认构造函数,对吗
但是如果你这样做
B obj2=new B()代码>
根据本教程,将生成B的默认构造函数,
该构造函数将调用超类的无参数构造函数,
这将反过来调用Object中的构造函数
那么超类什么时候没有无参数构造函数呢
在驱动程序类的main
方法中
A obj1 = new A();
将创建一个默认构造函数
在驱动程序的main
方法中,您无法创建默认构造函数。如果定义了,您可以使用它;如果未定义,则会出现编译错误
那么超类什么时候没有无参数构造函数呢
当它有其他构造函数时,所有构造函数都接受一些参数。以下是一个例子:
class SuperA {
public SuperA(String str) { ... }
public SuperA(int num) { ... }
}
上面,SuperA
有两个构造函数-一个接受字符串
,另一个接受int
。它们都不是默认值,因为它们都采用参数
如果您创建一个派生类DerivedB extensed SuperA
,并且没有定义任何构造函数,那么您将得到一个编译错误。当您没有提供构造函数时,默认构造函数由编译器定义
那么这个
public class A{}
将由编译器表示为:
public class A
public A() {
super(); //invokes Object's default constructor
}
}
因为我对A
的定义没有定义明确的构造函数
在上面的示例中,A
隐式扩展了对象
,并且对象的
默认构造函数在执行super()
时由编译器自动调用。对于可能扩展A
的任何类也是如此,例如:
public class B extends A {}
将由编译器实现,类似于:
public class B extends A {
public B() {
super(); //invokes A's default constructor
}
}
如您所见,它将链接对象的默认构造函数,然后链接A
的默认构造函数,最后链接B
的默认构造函数
>那么超类什么时候没有无参数构造函数?
当您显式定义一个无参数构造函数时,它不会有无参数构造函数。例如,如果我将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反编译器工具,让您可以查看编译器生成的代码
您可以编译我的示例,然后反编译它们以查看生成的代码,例如
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."<init>":()V
4: return
}
那我就可以了
javac A.java
javap A
它产生了
class A {
A(java.lang.String);
}
这表明您在原始问题中引用的规范中阅读的内容是真实的
那么超类什么时候没有无参数构造函数呢
如果您添加了超类的任何其他构造函数,但忘记添加任何参数构造函数,编译器会抱怨。在这种情况下,不提供超类的默认构造函数
class A {
A(java.lang.String);
}