何时在调用构造函数后创建Object

时间:2012-02-21 17:14:22

标签: java object constructor creation

考虑以下代码类。




     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!!
中的第一个输出行,因为当调用类A的构造函数时,它会在调用callCreation之前隐式调用超类的构造函数(java.lang.Object)( )类A的构造函数中的方法。这也是B和C类的情况。在那种情况下,当调用B的构造函数时,调用流程通常应该是:B的构造函数 - > A的构造函数 - > java.lang.Object的构造函数 - >回到A的callCreation()方法来完成调用A的构造函数。如果是这样,如何打印被覆盖的值而不是超级类的值?所以问题是'什么时候创建了一个类的对象?换句话说,只有在构造函数完成调用/初始化其自身内的所有元素之后,才应创建类的对象。如果是这样,如何从子类调用方法而不是从父类调用?

2 个答案:

答案 0 :(得分:4)

B和C中的callCreation方法覆盖来自A的方法。因此,当在构造函数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);
    }
}

答案 1 :(得分:1)

以这种方式思考会使其更加明显: 当正在创建类型B的对象时,super()关键字调用A构造函数, 然后在构造函数中执行“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类延伸B {

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();

}

}