Java继承关系、构造器的内存分析

由于ZangXT对这个问题提出了质疑, 所以, 在文末, 又追加了一个测试使用super绕过多态的例子, 以期证明, 构造一个对象的时候, 隐含的持有了父类的引用(或者以更合适的名词称呼: 向上代理)

 

 

 

问题就是上面写的这样,下面是内存分析.

 

执行new   MyC();时候的调用顺序.
1.   ClassLoader加载MyC这个类.
2.   准备调用MyC的构造方法.
3.   准备调用MyC的父类MyB的构造方法.
4.   准备调用MyB的父类MyA的构造方法.
5.   准备调用MyA的父类java.lang.Object的构造方法.
6.   执行java.lang.Object的构造方法.
7.   初始化MyA类的成员变量,a=1;
        注意:此时堆栈中对象的分布是MyC的对象持有MyB对象的一个引用,MyB对象持有MyA对象的一个引用,MyA对象持有java.lang.Object对象的一个引用,MyA,MyB,MyC对象中各有一个成员变量a,一定注意,这个时候,堆栈中有三个a,此时MyA的成员变量a=1;MyB和MyC的成员变量a=0;
8.   执行MyA的构造方法,调用print方法      
      注意:这里有多态,我们调用的方法实际上是MyC对象重写的方法,也就是说内存代码区向外提供调用的print方法是MyC的print方法,由于MyC中的成员变量a=0,所以此时打印 "ooo0 ";
9.   初始化MyB的成员变量.和第7条同理,此时堆栈中MyA的a=1,MyB的a=2,MyC的a=0;
10.   执行MyB的构造方法.和8同理,调用的还是MyC的print方法,所以打印的是 "ooo0 ";
11.   初始化MyC的成员变量.和第7条同理,此时堆栈中MyA的a=1,MyB的a=2,MyC的a=3;
12.   执行MyC的构造方法.和8同理,调用的是MyC的print方法,此时MyC的成员变量a=3,所以打印的是 "ooo3 ";

做这个内存分析的时候,主要考虑new   MyC();这一句执行的过程:
1.   ClassLoader加载MyC;
2.   进入MyC的构造器,首先构造MyC的父类,直到Object,Object之后怎么处理就不清楚了.
3.   处理完父类构造器之后,处理成员变量的初始化.
4.   然后执行构造器中的代码.

相关的东西:
多态:一个类继承关系中的重写的方法,在调用的时候,只有一个,那就是重写了那个方法的备份最小的类中的方法体.

 

 

以下是试图证明存在super引用的代码. 感兴趣的朋友可以把子类B中的f()方法中的super.m()换成this.m(), 就能看到区别了.

 

父类的代码

 

 

子类的代码:

 

测试代码:

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值