2011-09-20 159 views
5

我有三类:构造函数调用

public class A { 
    public A(){ 
     System.out.println("in A"); 
    } 
} 


public class B extends A{ 

    public B(){ 
     System.out.println("in b"); 
    } 
} 


public class C extends B{ 

    public C(){ 
     System.out.println("in C"); 
    } 
} 

现在我真的不知道该如何构造函数调用的工作。 如果我实例化C c= new C();,按什么顺序(以及为什么顺序)构造函数被调用。 如果我实例化类C,那么它不应该只是检查C类是否有任何构造函数,如果它确实,它应该使用它?

它为什么输出 - > In A In B In C?

只有当它没有在它自己的类中找到构造函数时,它不会在层次结构中上升吗?或者超类的构造函数每次都隐式调用?

回答

3

超级构造函数默认从基类构造函数中调用。

你应该使用super调用一个超类构造函数的唯一情况是当你需要显式地将一个参数传递给超类构造函数本身时。

所以答案是肯定的,他们都被称为。顺序是从层次结构中的最高级到基类,因此:A,B,C。

1

当调用构造函数时,它首先调用super(),因此尽管堆栈跟踪将显示:C- > B-> A,居然会先调用和C将会一次调用,从而打印将显示:

in A 
in B 
in C 
+0

“实际上A将被首先调用”的措辞是误导性的。 C的构造函数首先被调用,因为您正在初始化类型C的实例。打印顺序是由层次结构中构造函数的控制流引起的,而不是因为A的构造函数被首先调用。 –

+0

@Anthony:我试着在我的答案中解释这个想法,如果你有一个更好的术语,我会很乐意使用它,不幸的是,英语不是我的母语..:\ – amit

0

super()是隐含的,因为默认的构造函数,如果没有构造函数声明。

的构造向上运行:

C calls B, B calls A, A calls to Object that does nothing and return to A, then outputs and return the flow to B, that outputs and return to C that outputs. 
2

默认构造函数总是被调用,调用自上而下的 - 从最上层的超一流最低基类。

请注意,super(...)调用仅适用于参数化构造函数。在你的情况下,你没有任何,所以默认会自动调用。

+0

+1对于很好的解释;-) – Deepak

0

默认情况下会调用超级构造函数。它在派生类的构造函数中的任何代码行之前执行。所以如果你调用新的C(),A的构造函数是运行的,那么B的,然后是C中的任何东西。

0

是的,当你没有定义任何构造函数时,它会隐含地创建默认构造并调用它。现在,当你扩展任何类,然后像C类一样,它会使用它的构造函数,但是它没有找到显式调用超类,因此编译器隐式地调用超类构造函数。那为什么当我们调用超类的构造函数语句总是第一个像这样

public C(){ 
    super(); 
} 

,如果你打电话给你得到错误的超类的构造函数之前写的任何陈述

0

看看Java语言规范

“如果构造函数体不是以明确的构造函数调用开始的,并且声明的构造函数不是原始类Object的一部分,那么构造函数体将由编译器隐式地假定为以超类构造开始或调用“super();”,它的直接超类的构造函数的调用不接受任何参数。“

http://java.sun.com/docs/books/jls/second_edition/html/classes.doc.html#41652

0

A级为B和B类的超类是超类C的这意味着A在它们之间的顶部位置,其中B是在顶部为C,旁边的一个而C坐在B的底部。所以A类先执行然后B然后C执行。这就像超类中Java的优先级。