写点什么

Java 多态实现原理,java 同步锁原理

用户头像
极客good
关注
发布于: 刚刚

方法区:方法区和 JAVA 堆一样,是各个线程共享的内存区域,用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。?运行时常量池:它是方法区的一部分,Class 文件中除了有类的版本、方法、字段等描述信息外,还有一项信息是常量池,用于存放编译器生成的各种符号引用,这部分信息在类加载时进入方法区的运行时常量池中。?方法区的内存回收目标是针对常量池的回收及对类型的卸载。


#####Java?的方法调用方式


Java?的方法调用有两类,动态方法调用与静态方法调用。


  • 静态方法调用是指对于类的静态方法的调用方式,是静态绑定的

  • 动态方法调用需要有方法调用所作用的对象,是动态绑定的。


类调用?(invokestatic)?是在编译时就已经确定好具体调用方法的情况。


实例调用?(invokevirtual)则是在调用的时候才确定具体的调用方法,这就是动态绑定,也是多态要解决的核心问题。


JVM?的方法调用指令有四个,分别是?invokestatic,invokespecial,invokesvirtual?和?invokeinterface。前两个是静态绑定,后两个是动态绑定的。本文也可以说是对于 JVM 后两种调用实现的考察。


方法表与方法调用


如有类定义?Person, Girl, Boy


class Person {public String toString() {return "I'm a person.";}public void eat() {}public void speak() {}}


class Boy extends Person {public String toString() {return "I'm a boy";}public void speak() {}public void fight() {}}


class Girl extends Person {public String toString() {return "I'm a girl";}public void speak() {}public void sing() {}}


当这三个类被载入到?Java?虚拟机之后,方法区中就包含了各自的类的信息。Girl?和?Boy?在方法区中的方法表可表示如下:



可以看到,Girl?和?Boy?的方法表包含继承自 Object 的方法,继承自直接父类 Person 的方法及各自新定义的方法。注意方法表条目指向的具体的方法地址,如?Girl?继承自?Object?的方法中,只有?toString()?指向自己的实现(Girl?的方法代码),其余皆指向?Object?的方法代码;其继承自于?Person?的方法?eat()?和?speak()?分别指向?Person?的方法实现和本身的实现。


如果子类改写了父类的方法,那么子类和父类的那些同名的方法共享一个方法表项。


因此,方法表的偏移量总是固定的。所有继承父类的子类的方法表中,其父类所定义的方法的偏移量也


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


总是一个定值。Person?或?Object 中的任意一个方法,在它们的方法表和其子类?Girl?和?Boy?的方法表中的位置 (index) 是一样的。这样?JVM?在调用实例方法其实只需要指定调用方法表中的第几个方法即可。


如调用如下:


class Party {void happyHour() {Person girl = new Girl();girl.speak();}}


当编译?Party?类的时候,生成?girl.speak()的方法调用假设为:????Invokevirtual #12


设该调用代码对应着?girl.speak(); #12?是?Party?类的常量池的索引。JVM?执行该调用指令的过程如下所示:



用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
Java多态实现原理,java同步锁原理