关于对象初始化内部顺序的个人见解

本文详细解析了Java中继承关系下父类与子类构造方法的执行顺序及变量初始化的过程,通过具体示例帮助理解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们总会遇到这样的代码,
`public class Test {

public int a = 1;

}
`
当new一个这样的对象后,里面就有一个叫做‘a’的整型变量,其值为1;
但是new这个对象的具体过程,在这之前,我并不是非常的清楚,当老师出了一道有关知识点的面试题后,我才搞懂其中的顺序,废话不多说,上题:


public class Parent {

    public int a = 11;

    public Parent() {
        printA();
    }

    public void printA(){
        System.out.println(a);
    }
}


public class Child extends Parent{

    public int a = 250;
    {
        a = 251;
    }

    public Child() {
        super();
    }

    @Override
    public void printA() {
        System.out.println(a);
    }

    public static void main(String[] args) {
        new Child();
    }
}

写出程序的运行结果
大家可以先自己做一下虚拟机,编译运行一下,看看结果是多少

==============萌萌哒分割线==================

运行结果为
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=
=

0

我刚开始对这个结果也十分的不理解,现在我为大家解释一下:
当为继承关系的两个类进行编译运行的时候,首先虚拟机会先执行所有的静态数据块,先父类静态数据块后子类静态数据块,然后再执行父类的非静态数据块和父类的构造方法,最后执行子类的非静态数据块和构造方法。

而且,在Child类中出现的这条语句“public int a = 250;”,只是先分配了空间,在父类的构造方法结束之前,并不会进行“250”的赋值操作,当成员变量未进行初始化时,虚拟机会对其进行默认值得赋值操作,所以其值一开始是

“0”

我们再来看代码,将代码的执行过程仔细的过一遍:

  1. 第一步,当代码执行到main方法时,new了一个Child对象,虚拟机在内存中分配了空间,并有两个名为“a”的变量,为了区别表示,分别叫为“pa”和“ca”。随后虚拟机先执行所有的静态数据块,但此时并没有,所以没有显式的效果
  2. 第二步开始执行Parent类的非静态语句块和构造方法,当Parent的父类(Object)完成初始化后,“pa”变量被赋值为11,然后调用了“printA();”,由于Child类已经重写了Parent类中的printA()方法,所以现在调用的是Child类中的printA()方法,而此时变量“ca”还为默认值0,所以调用方法后,输出结果为0;
  3. 第三步,执行Child类的非静态语句块和构造方法,此时父类的构造方法已经执行结束(相当于“super();”语句执行完毕),所以变量“ca”被赋值250,随后执行非静态语句块,“ca”的值被改成为251,然后语句“new Child();”语句执行完毕;

    这就是完整的执行过程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值