调用构造函数后何时创建对象

发布于 2025-01-07 17:19:51 字数 1700 浏览 0 评论 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!!
is printed because when the constructor of class A is called, it calls the super class's constructor (java.lang.Object) implicitly before calling the callCreation() method in the class A's constructor. And this will be the case for B and C classes too. In that case when the constructor of B is called the call flow should be typically : B's constructor -> A's Constructor -> java.lang.Object's Constructor -> come back to A's callCreation() method to finish calling A's constructor. If so how is the overridden value printed and not the super class's value is printed? So the question is 'when is an object of a class created exactly? to put it in other words, the object of a class should be created only after the constructor finishes calling/initializing all the elements within itself. If so how can a method be called from a child class and not from the parent class?

Consider the following code classes.




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

The output of running the class C is given below.

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

The first output line in the output

A Created!!

is printed because when the constructor of class A is called, it calls the super class's constructor (java.lang.Object) implicitly before calling the callCreation() method in the class A's constructor. And this will be the case for B and C classes too. In that case when the constructor of B is called the call flow should be typically : B's constructor -> A's Constructor -> java.lang.Object's Constructor -> come back to A's callCreation() method to finish calling A's constructor. If so how is the overridden value printed and not the super class's value is printed? So the question is 'when is an object of a class created exactly? to put it in other words, the object of a class should be created only after the constructor finishes calling/initializing all the elements within itself. If so how can a method be called from a child class and not from the parent class?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅笑依然 2025-01-14 17:19:51

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

The callCreation methods in B and C override the method from A. So when the method is called in the constructor A the implementations in B and C will be run, even though the constructors of B and C have not been executed yet. This is possible because constructors don't actually create the object, rather they are called to initialize some moments after the JVM has created it.

In general it's a very bad idea to call methods that can be overridden from a constructor for this very reason. A method in B or C may assume that the constructor and object initializers have already been run, and read an unexpected value from a field. For example the following ends up printing "B Created!! null" because the field still has not be assigned its value.

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

    protected void callCreation()
    {
        System.out.println("B Created!! "+msg);
    }
}
月下客 2025-01-14 17:19:51

这样思考就更明显了:
当创建 B 类型的对象时 super() 关键字调用 A 构造函数,
然后在构造函数中执行“this.callCreation()”,它引用当前
对象为B,因此调用当前对象(B)对应的callCreation。
对 C 执行相同的过程。

public class A {

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

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

}

class B extends A {

public B() {
    super();
}

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

}

class C extends 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();

}

}

thinking in this way makes it more obvious:
when an object of type B is being created super() keyword calls the A constructor,
then in A constructor "this.callCreation()" is executed, which refers to the current
object which is B, so callCreation corresponding to the current object(B) is called.
the same process is done for C.

public class A {

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

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

}

class B extends A {

public B() {
    super();
}

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

}

class C extends 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();

}

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文