Java继承的底层原理浅析

前言

这两天在重温java继承,做了几个实例,特别是在做多态实例时对java底层产生了猜想,有时候会根据我的猜想出结果,有时候会有差错,赶紧查阅资料,浅析一下继承的底层.

方法区概念的引入

  1. 方法区,与java堆一样,是各个线程共享的内存区域.
  2. 方法区在JVM启动的时候被创建,并且它的实际的物理内存空间中和java堆区一样都可以是不连续的.
  3. 方法区的大小决定了系统可以保存多少个类,如果系统定义了太多的类,导致方法区溢出,虚拟机同样会抛出内存溢出错误.(方法区加载大量的第三方的jar包,tomcat部署过多,大量动态的生成反射类也会).
  4. 关闭JVM就会释放这个区域的内存

栈堆方法区

之前只知道java底层有java栈和java堆,思考底层运行的时候囿于此,所以有纰漏.
由于对于一个类class来说,其创建的实例是独一无二的,故其引用放在栈,自身放在堆中.而静态变量,方法以及Class对象则是堆所有类实例来说是共享的,单独处理,放在方法区中.

类加载

类加载过程包括:
加载:根据类名称获取二进制字节流,转化成方法区数据结构,并在堆中生成类class对象
验证:验证是否安全
准备:为静态变量在方法区分配内存
解析:把符号引用转化成直接引用
初始化:一般在new对象的时候会触发初始化,并为静态变量附上真实的值。

上面也说明了:类加载后会在方法区存放该类的信息,创建对象时,创建出一个对象存放到方法区,并在栈中有指向该对象的引用,堆中每个对象除了保存类的实例变量之外,还保存着实际类信息的引用,如下图所示:
在这里插入图片描述
我们先来看animal.animalShout();这句代码的执行过程是:
查看animal的对象类型,找到Cat类型,在Cat类型中找animalShout方法,发现没有,到父类中寻找
在父类Base中找到了方法animalShout,开始执行animalShout方法
在animalShout方法中发现调用了shout方法,就从Cat类型开始寻找shout方法
在Child类型中找到了shout()方法,执行Cat中的shout()方法,执行完后返回animalShout方法
继续执行action方法,输出打印信息
寻找要执行的实例方法的时候,是从对象的实际类型信息开始查找的,找不到的时候,再查找父类类型信息。
如果继承的层次比较深,那么如果调用的存在最底层的父类,则调用的效率是比较低的,所以系统使用一种称为虚方法表的方法来优化调动的效率。
所谓虚方法表,就是在类加载的时候,为每个类创建一个表,这个表包括该类的对象所有动态绑定的方法及其地址,包括父类的方法,但一个方法只有一条记录,子类重写了父类方法后只会保留子类的。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值