Javadoc提到Object类有一个public no-arg构造函数。但是Object的源代码中没有任何显式的构造函数。显然编译器为它生成了一个。但是,如果我在构造函数即将返回时看到调用堆栈跟踪(如下所示),我在该跟踪中看不到对Object.<init>
的任何调用。
所以问题是,Object类是否有一个默认的构造函数,正如doc所说的那样?如果是,为什么我在调用堆栈跟踪中看不到它?
public ConTest()
{
new Throwable().printStackTrace();
}
结果:
java.lang.Throwable
at ConTest.<init>(ConTest.java:8)
at ConTest.main(ConTest.java:16)
答案 0 :(得分:24)
超级构造函数在sub / base构造函数之前运行。在您的示例中,在执行new Throwable().printStackTrace()
时,已经运行了Object的构造函数。
更明确的代码版本:
public ConTest()
{
super();
new Throwable().printStackTrace(); // you will not see super() (Object.<init>) in this stack trace.
}
答案 1 :(得分:6)
您没有在堆栈跟踪中看到它,因为它已被调用。您的代码中会抛出异常。
您的代码相当于写作:
public ConTest() {
super(); // this will call the Object constructor
new Throwable().printStackTrace();
}
答案 2 :(得分:6)
您没有在堆栈跟踪中看到它,因为在您的new Throwable().printStackTace()
调用之前调用了超类的构造函数。编译器实际创建的是跟随。
public ConTest()
{
super(); // This is the call to the base class constructor
new Throwable().printStackTrace(); // already back from the base class constructor
}
答案 3 :(得分:6)
是的,对象类有一个默认的构造函数,正如文档所说。
如您所知,您可以在命令提示符中使用javap -c ConTest进行检查 你可以看到它在下面的代码行号:1
中调用对象类默认构造函数()C:\stackdemo>javap -c ConTest
Compiled from "ConTest.java"
public class ConTest extends java.lang.Object{
public ConTest();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: new #2; //class java/lang/Throwable
7: dup
8: invokespecial #3; //Method java/lang/Throwable."<init>":()V
11: invokevirtual #4; //Method java/lang/Throwable.printStackTrace:()V
14: return
public static void main(java.lang.String[]);
Code:
0: new #5; //class ConTest
3: dup
4: invokespecial #6; //Method "<init>":()V
7: astore_1
8: return
}
谢谢
答案 4 :(得分:2)
如上所述,super()是构造函数和方法中的第一个调用。更多信息here
编译类时,Java编译器会为您在类的源代码中声明的每个构造函数创建一个实例初始化方法。虽然构造函数不是方法,但实例初始化方法是。它有一个名称
<init>
,一个返回类型,void和一组参数,这些参数与生成它的构造函数的参数相匹配