写点什么

Java 多态实现原理,招银网络科技 java 面试

作者:Java高工P7
  • 2021 年 11 月 10 日
  • 本文字数:1621 字

    阅读完需:约 5 分钟

方法区:方法区和 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?的方法实现和本身的实现。


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


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


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


的子类的方法表中,其父类所定义的方法的偏移量也总是一个定值。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?执行该调用指令的过程如下所示:



(这里有个错误,上图为 ClassReference 常量池而非 Party 的常量池)【再次拓展】


常量池在逻辑上可以分成多个表,每个表包含一类的常量信息,本文只探讨对于 Java 调用相关的常量池表。


CONSTATNT_Method_info**:**类方法引用表;包含引用的任何类型方法的描述信息,主要包括类信息索引和名字类型索引。


CONSTATNT_Class_info**:**类信息表;包含任何被引用的类或接口的 ‘符号引用’ ,每一个条目主要包含一个索引,指向<u style="box-sizing: inherit;">CONSTA_Utf8_info</u>表,表示该类或接口的全限定名。


CONSTATNT_NameAndType_info:名字类型表;包含引用的任意方法或字段的名称和描述符信息在字符串常量中的索引。


CONSTATNT_Utf8_info:字符串常量表; 该表包含该类所使用的所有字符串常量,比如代码中的字符串引用、引用的类名、方法的名字、其他引用的类与方法的字符串描述等等。其余常量池表中所涉及到的任何常量字符串都被索引至该表。

用户头像

Java高工P7

关注

还未添加个人签名 2021.11.08 加入

还未添加个人简介

评论

发布
暂无评论
Java多态实现原理,招银网络科技java面试