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 ...
随机推荐
- 读取jar包内的文件内容
package com.chanpion.boot; import org.springframework.util.ResourceUtils; import java.io.File; impor ...
- 零基础逆向工程14_C语言08_指针02_反汇编
1.指针数组 5: char* keyword[] = {"if", "for", "while", "switch"} ...
- arcgis jsapi接口入门系列(9):可以同时显示多个的地图popup
jsapi有提供popup功能,但缺点很多,例如地图上只能同时显示一个popup,popup内容有限制等 本文提供另一个方法,原理不用jsapi,在地图外用一个普通的div放在地图上面,再监听地图的鼠 ...
- 深入理解Java虚拟机--个人总结
JVM内存区域 我们在编写程序时,经常会遇到OOM(out of Memory)以及内存泄漏等问题.为了避免出现这些问题,我们首先必须对JVM的内存划分有个具体的认识.JVM将内存主要划分为:方法区. ...
- pytest+allure2+jenkins环境部署
1.pycharm安装allure-pytest 2.jenkins -> 系统管理 -> 插件管理 -> 可选插件中过滤Allure,勾选对应插件安装 如下图: 3.安装完插件后 ...
- BZOJ 1806: [Ioi2007]Miners 矿工配餐
ime Limit: 10 Sec Memory Limit: 64 MBSubmit: 910 Solved: 559[Submit][Status][Discuss] Description ...
- DDOS介绍
DDOS: Data Domain Operating System(DD OS),即数据域操作系统----管理EMC的数据域拷贝存储系统(powers EMC Data Domain dedupli ...
- WebClient UI和Tomcat的启动器
WebClient UI 我们在WebClient UI的开发工具里点了Test按钮, 会在浏览器以测试模式打开选中的view.这背后发生了什么事?注意浏览器地址栏的bspwd_cmp_test,这是 ...
- 日常-acm-开灯问题
开灯问题.有n盏灯,编号1-n.第一个人把所有的灯打开,第二个人按下所有编号为二的倍数的开关(全关掉),第三个人按下所有编号为三的倍数的开关,以此类推.一共k个人,问最后开着的灯的编号.输入n和k,输 ...
- Codeforces Round #321 (Div. 2) C Kefa and Park(深搜)
dfs一遍,维护当前连续遇到的喵的数量,然后剪枝,每个统计孩子数量判断是不是叶子结点. #include<bits/stdc++.h> using namespace std; ; int ...