欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2024-03-12 16:17:02
...

对象初始化全过程

例子:

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

输出结果:
JAVA---new对象初始化底层内存全过程(图解)
可能看到这个输出结果会觉得奇怪
但是我们要记住,构造函数先于显示初始化先执行的

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

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

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

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

于是输出:constructor code...9**
然后又把num重新赋值为10
JAVA---new对象初始化底层内存全过程(图解)
.
.
.
接着执行Zi()构造函数里面的show()方法,show()方法进栈
JAVA---new对象初始化底层内存全过程(图解)
.
.
.
接着执行show()方法里面的内容

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

于是输出: zi constructor...10
.
.
.
.
至此整个程序执行结束…
所以输出内容是
JAVA---new对象初始化底层内存全过程(图解)
一定要记得构造函数先于显示初始化执行…
执行完super后,才会执行显示初始化,然后再执行构造函数的初始化.

即:

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