JAVA---new对象初始化底层内存全过程(图解)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_42947972/article/details/102529076

对象初始化全过程

例子:

class Fu
{
    Fu0()
    {
        show();
    }
    void show()
    {
        System.out.println("hehe");
    }
}
class Zi extends Fu
{
    int num = 9;
    {
        System.out.println("constructor code..."+num);
        num = 10;
    }
    Zi()
    {
        System.out.println("zi constructor..."+num);
    }
    void show()
    {
        System.out.println("show.."+num);
    }
}
public class Demo{
    public static void main(String[] args){
        new Zi();
    }
}

输出结果:
在这里插入图片描述
可能看到这个输出结果会觉得奇怪
但是我们要记住,构造函数先于显示初始化先执行的

其实在Zi类构造函数中还有一个隐藏存在的super()

Zi()
    {
        super();//隐藏起来了
        System.out.println("zi constructor..."+num);
    }

我们将用下面这个例子了解new对象初始化的全部过程:

class Fu
{
    Fu0()
    {
        show();
    }
    void show()
    {
        System.out.println("hehe");
    }
}
class Zi extends Fu
{
    int num = 9;
    {
        System.out.println("constructor code..."+num);
        num = 10;
    }
    Zi()
    {
        super();
        //隐藏起来了,我们实际敲代码的时候是可以不写的,Java虚拟机会帮我们的
        System.out.println("zi constructor..."+num);
    }
    void show()
    {
        System.out.println("show.."+num);
    }
}
public class Demo{
    public static void main(String[] args){
        new Zi();
    }
}

内存图:
在这里插入图片描述
开始执行
.
.
.
执行Demo类,然后主函数main进栈
在这里插入图片描述
.
.
.
然后new Zi()类(这个属于匿名new对象)
由此Zi()类和Fu()类进栈,因为虚拟机会检查类是否有父类…
每个类其实一开始都有父类Object类也就是上帝类
比如Zi类如果不是继承Fu类的话是这样子的:class Zi extends Object
所以由于Zi类继承了Fu类,就不去继承Object类了
于是Zi类和Fu类一起加载进方法区(其实Demo类在一开始的时候也加载了,但是由于不够话,就不画出来了)
在这里插入图片描述
.
.
.

然后开始执行Zi类 :int num
它默认初始化为0(前面我们已经讲过了构造函数是**先于**显示初始化执行的)
于是开始执行Zi(){}构造函数
这时就会先执行super();发现里面有个Fu类于是执行Fu类
在这里插入图片描述
.
.
.
Fu类和Zi一样,先找一下有没有要默认初始化的,发现没有.
于是也执行Fu(){}构造函数.
一样的还是执行隐藏的super()(上帝类).
然后完毕之后,执行 show()方法.
于是show()方法进栈
在这里插入图片描述
.
.
.
show方法里有一个this用于找到在堆内存的地址.
这时他就会通过堆内存地址,进入方法区找一个show()方法
它会先进入Zi类找,发现有于是就执行了(没有的话会进入super寻找)
这时我们可以看堆内存的num还是等于0
于是就输出了show..0
在这里插入图片描述
.
.
.
执行完毕后show()方法开始退栈,然后发现Fu类已全部执行完毕.
于是执行Zi类,这时int num 开始显示初始化为9
在这里插入图片描述
.
.
.
完毕后执行代码块里面的内容

 {
        System.out.println("constructor code..."+num);
        num = 10;
   }

于是输出:constructor code...9**
然后又把num重新赋值为10
在这里插入图片描述
.
.
.
接着执行Zi()构造函数里面的show()方法,show()方法进栈
在这里插入图片描述
.
.
.
接着执行show()方法里面的内容

 System.out.println("show.."+num);

于是输出: zi constructor...10
.
.
.
.
至此整个程序执行结束…
所以输出内容是
在这里插入图片描述
一定要记得构造函数先于显示初始化执行…
执行完super后,才会执行显示初始化,然后再执行构造函数的初始化.

即:

Zi0()
    {
        super();//隐藏起来了
        //显示初始化 
        //构造初始
        System.out.println("zi constructor..."+num);
    }

猜你喜欢

转载自blog.csdn.net/weixin_42947972/article/details/102529076
今日推荐