JAVA---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()
{
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);
}
上一篇: 笔试 - 邪恶数字4与7
下一篇: 计算机常见的编码规范