Java中对象方法的调用过程&动态绑定(Dynamic Binding)
Java面向对象的最重要的一个特点就是多态, 而多态当中涉及到了一个重要的机制是动态绑定(Dynamic binding)。
之前只有一个大概的概念, 没有深入去了解动态绑定的机理, 直到很多公司都问到了动态绑定的实现, 然后。。。就真的没有然后了。
痛定思痛, 在<Core Java>找到了相关的章节,也算是对动态绑定的实现有了一个大概的了解。
对象是Java中最重要的概念, 弄清楚对象方法的调用执行过程会对Java对象有更深层了理解。下面是<Core Java>中对调用过程的详细描述:
1. 编译器首先查看对象声明的类型和方法名, 假设对象调用 x.f(param) ,x是声明为C类的对象, 需要注意的是由于存在方法的重载, 所以可能有多个名字为f,
但是参数类型、个数或者次序不一样的方法。 例如 f(int), f(double), f(string)。然后编译器会一一列举出所有C类中方法名为 f 的方法以及C类的父类中属性为public
而且方法名为 f 的方法。
至此, 编译器已经获得了所有可能被调用的候选方法。
2. 编译器查看调用方法时传入的参数类型, 然后去上述已经获得的候选方法中进行查找, 如果这些方法中存在一个与提供的参数类型完全匹配的就会选择这个方法。
这个过程被称为重载解析(overloading resulution)。 例如调用 x.f("hello"), 编译器会通过重载解析挑选f(string)而不是f(int)。
如果编译器没有找到与参数类型匹配的方法, 就会报告一个错误。
至此, 编译器已经获得需要调用的方法的名字和参数类型。
3. 如果是private, static, final修饰的方法或者构造器(constructor), 那么编译器可以准确的指导应该调用哪个方法, 这种方式称为静态绑定(static binding)
即在编译期间已经把对象和方法进行了绑定。 除此之外, 如果调用的方法要一依赖于对象的实际类型, 在运行时实现对象和方法绑定的称为动态绑定(Dynamic binding)。
4. 当程序运行并且采用动态绑定调用方法时, 虚拟机JVM一定会调用与x所引用的对象的实际类型最相符合的那个类的方法。
例如, x的实际类型是C, C是B的子类, 在调用 x.f("hello")时首先会去看C类中是否有 f(string) 方法, 如果有则直接调用, 如果没有则在C类的父类B中寻找f(string)方法。
由于每次调用发发都要进行搜索, 由此带来的后果就是时间开销较大,因此虚拟机采用了一种策略---> 方发表(method table), 其实我感觉就是借用了数据结构中的散列表。
JVM 会预先为每个类都创建一个方法表(method Table)方发表中勒出了所有的签名和实际调用方法。
举个例子, Java虚拟机预先为 Employee 和 Manager 两个类生成方发表
medthod Table ----Employee method Table-----Manager extends Employee
(签名) (调用) (签名) (方法调用)
getName() -----> Employee.getName() getName() ---------> Employee.getName()
getSalary() -----> Employee.getSalary() getSalary() ---------> Manager.getSalary()
getHireDay() -----> Employee.getHireDay() getHireDay() ---------> Employee.getHireDay()
raiseSalary() -----> Employee.raiseSalary() raiseSalary() ---------> Employee.raiseSalary()
setBounus() ---------> Manager.setBounus()
如果对 e.getSalary() 精选解析, 过程如下:
1. JVM 会提取e的实际类型的方发表, 例如是Employee类型则会提取左表, 如果是Manager类型则会提取右表。
2. JVM 会在方发表中搜索方法的签名, 例如e.getSalary()则会去每个方发表左边的签名列中寻找与getSalary()匹配的方法。
3. JVM 调用该方法。
Java中对象方法的调用过程&动态绑定(Dynamic Binding)的更多相关文章
- Java 调用对象方法的执行过程
弄清调用对象方法的执行过程十分重要.下面是调用过程的详细描述: 1) 编译器查看对象的声明类型和方法名.假设调用x.f(param),且隐式参数x声明为C类的对象.需要注意的是:有可能存在多个名为f, ...
- JAVA中native方法调用
在Java中native是关键字.它一般在本地声明,异地用C和C++来实现.它的声明有几点要注意:1)native与访问控制符前后的关系不受限制.2)必须在返回类型之前.3)它一般为非抽象类方法.4) ...
- Delphi动态事件深入分析(对象方法在调用的时候会传递一个隐含的Self指针,而该指针的值在EAX中。即左边第一个参数)
Delphi动态事件深入分析 2009-2-7 作者:不得闲核心提示:本实验证明了在类中方法的调用时候,所有的方法都隐含了一个Self参数,并且该参数作为对象方法的第一个参数传递... 首先做一个空窗 ...
- java中,方法可以访问他的类对象的任何私有特性
java中,方法可以访问他的类对象的任何私有特性 读一本书(Core Java for the Impatient)时,发现这个注意,以前的时候没有在意,今天仔细想想发现记忆不深刻.记录一下 下面代码 ...
- java中的方法——重载yu重写(转)
重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. ...
- Java中对象的深复制和浅复制详解
1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...
- InvocationHandler中invoke()方法的调用问题
转InvocationHandler中invoke()方法的调用问题 Java中动态代理的实现,关键就是这两个东西:Proxy.InvocationHandler,下面从InvocationHandl ...
- Java09-java语法基础(八)java中的方法
Java09-java语法基础(八)java中的方法 一.方法(函数/过程):是一个程序块,可以完成某种功能 1.java中方法的定义格式 [访问控制修饰符] 返回值类型 方法名(参数列表){ 方 ...
- 对Java中HashCode方法的深入思考
前言 最近在学习 Go 语言,Go 语言中有指针对象,一个指针变量指向了一个值的内存地址.学习过 C 语言的猿友应该都知道指针的概念.Go 语言语法与 C 相近,可以说是类 C 的编程语言,所以 Go ...
随机推荐
- Spring Boot Security配置教程
1.简介 在本文中,我们将了解Spring Boot对spring Security的支持. 简而言之,我们将专注于默认Security配置以及如何在需要时禁用或自定义它. 2.默认Security设 ...
- ubuntu中执行定时任务crontab
今天研究了下ubuntu里的crontab内置指令.这是设置定时执行脚本任务的指令,我先测试了下最基础的执行. 第一次使用crontab 时,会出现 no crontab for root - usi ...
- Echarts的重点
官网中,主要看文档的”教程“和”配置项手册“这两部分 1 下载 引入js 页面放一个容器,一定要设宽高 创建对象:var myChart = echarts.init(document.getElem ...
- git-gui:使用终端打开以后出现错误提示 Spell checking is unavable
参考链接:http://www.lai18.com/content/10706682.html 安装了git-gui,打开以后出现以下提示: Spell checking is unavable: e ...
- SpringBoot:异步开发之异步调用
前言 除了异步请求,一般上我们用的比较多的应该是异步调用.通常在开发过程中,会遇到一个方法是和实际业务无关的,没有紧密性的.比如记录日志信息等业务.这个时候正常就是启一个新线程去做一些业务处理,让主线 ...
- Git中文件属性的变化,被认为是文件有改动
问题描述: 1. 从公司的git服务器上, 下载最新的代码(zip格式), 解压缩出来, 2. 过一段时间, 去执行git pull代码, 出现如下情况: $ git pull Updating ...
- 如何提高Mysql的查询效率???
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- ABAP,Java和JavaScript的序列化,反序列化
ABAP 1. ABAP提供了一个工具类cl_proxy_xml_transform,通过它的两个方法abap_to_xml_xstring和xml_xstring_to_abap实现两种格式的互换. ...
- 如何在SAP云平台的Cloud Foundry环境下添加新的Service(服务)
我想在SAP云平台的Cloud Foundry环境下使用MongoDB的服务,但是我在Service Marketplace上找不到这个服务. cf marketplace返回的结果也没有. 解决方案 ...
- Firefox火狐广告过滤插件Adblock Plus过滤规则包[中文维护小组]
如果你经常使用Firefox火狐浏览器那么一定知道Adblock Plus这款广告过滤插件,功能非常强大,但是Adblock Plus广告过滤插件自带的过滤规则并不多,而且也不太适合我们中国的网站,在 ...