java向上转型时堆上发生了什么?
PHP中文网
PHP中文网 2017-04-17 13:24:52
[Java讨论组]
javaclass Base{
    public int a ;
    public int b;
    public void f();
}

class A extends Base{
    public int c;
}

如上面的两个类
定义
A a = new A();
Base b = (Base) a;
Base c = a;
当定义a时,内存中在栈上存储对A对象的引用a,在堆上生成A对象
当定义b时,内存中在栈上存储Base对象的引用,那么在堆上会是什么样的变化?
当定义c时,栈和堆上分别有什么生成?

PHP中文网
PHP中文网

认证高级PHP讲师

全部回复(3)
PHPz

java里对象的内存分布并没有在标准里规定, 是和 具体jvm实现相关的. jvm spec 8, section 2.7

对sun java来说, 你的代码, 在堆里只有一个对象, 就是class A. 具体在内存里, 应该有 java 对象头(指定此对象对应的class), 各个fields(包含其parent class的各个域), 还有padding. 有兴趣的话, 可以去玩一玩UnSafe, 看看java对象的内存分布. 随便找一个link:
http://ifeve.com/sun-misc-unsafe/

然后你定义的三个引用, 其实都指向同一个A对象. 这些引用, 只在编译器有意义. 这么说吧, 比如Base和A 里都有f()函数, 然后你用这三个引用去调用f(), 最终调用的都是 A里的f(). 因为 上面说了, 此java对象, 在java对象头中包含了 它真正是哪个class的信息.

高洛峰

定义c的时候栈上还是Base对象的引用,这个是在编译的时候确定的,但是堆上会有什么变化,个人猜测应该没啥变化吧,还真是比较偏的问题,有空研究研究

阿神

java在调用子类的构造方法之前会调用父类的构造方法,所以 new A()之后,堆上有A和Base两个对象,Base b =(Base)a,应该会把生成的Base对象的引用赋值给b,对于 c=a,其实c是指向 A的。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号