2012-02-21 67 views
0

请考虑以下代码类。何时调用构造函数创建对象




    public class A 
    { 
     public A() 
     { 
      callCreation(); 
     } 

     protected void callCreation() 
     { 
      System.out.println("A Created!!"); 
     } 
    } 




    public class B extends A 
    { 
     protected void callCreation() 
     { 
      System.out.println("B Created!!"); 
     } 
    } 


    public class C extends B 
    { 
     protected void callCreation() 
     { 
      System.out.println("C Created!!"); 
     } 

     public static void main(String[] args) 
     { 
      A a = new A(); 
      A b = new B(); 
      A c = new C(); 
     } 
    } 

运行C类的输出如下。

 
A Created!! 
B Created!! 
C Created!! 

在输出

A Created!!
第一输出线被隐式要求在所述callCreation()方法之前打印,因为当A类的构造函数被调用时,它调用超类的构造函数(java.lang.Object中) A类的构造函数。 B和C类也是如此。在这种情况下,当调用B的构造函数时,调用流应该是典型的:B的构造函数 - > A的构造函数 - > java.lang.Object的构造函数 - >返回A的callCreation()方法来完成调用A的构造函数。如果是这样,打印的值是如何被打印的,而不打印超类的值?所以问题是'什么时候创建了一个类的对象?换句话说,只有在构造器完成调用/初始化其内部的所有元素后,才能创建类的对象。如果是的话,如何从一个子类而不是从父类调用一个方法?

回答

4

callCreation方法在B和C 覆盖从A的方法因此,当调用该方法在构造函数中的B和C的实现将运行,即使B和C的构造函数都没有执行尚未。这是可能的,因为构造函数实际上不创建对象,而是在JVM创建它之后的某些时刻调用初始化

通常,由于这个原因,调用可以从构造函数重写的方法是非常糟糕的主意。 B或C中的方法可能会假定构造函数和对象初始值设定项已经运行,并从字段中读取一个意外的值。例如,以下结果是打印"B Created!! null",因为该字段仍未分配其值。

public class B extends A 
{ 
    final String msg = "Yes!"; 

    protected void callCreation() 
    { 
     System.out.println("B Created!! "+msg); 
    } 
} 
+0

+1正确 - 它总是从相同的构造函数中调用。唯一的区别是通话去的地方。 – 2012-02-21 17:17:07

+0

不是jvm需要一个对象来调用它的方法吗?请在下面的答案中找到我的评论。 – user1223879 2012-02-21 17:31:56

+0

是的;实际上它也需要一个运行构造函数*的对象。该对象在构造函数执行前很久就存在。 – Joni 2012-02-21 17:33:44

0

在这种方式思维使得它更明显: 正在创建乙类型的对象时超级()关键字调用的构造方法, 然后在构造函数“this.callCreation()”被执行时,它指的是当前对象是B,所以调用对应于当前对象(B)的callCreation。 相同的过程是为C.完成

公共类A {

public A() { 
    this.callCreation(); 
} 

protected void callCreation() { 
    System.out.println("A Created!!"); 
} 

}

类B扩展A {

public B() { 
    super(); 
} 

protected void callCreation() { 
    System.out.println("B Created!!"); 
} 

}

C类延伸乙{

public C() { 
    super(); 
} 

protected void callCreation() { 
    System.out.println("C Created!!"); 
} 

public static void main(String[] args) { 

     A a = new A(); 
     A b = new B(); 
     A c = new C(); 

} 

}

相关问题