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 assert 用法
spring在提供一个强大的应用开发框架的同时也提供了很多优秀的开发工具类,合理的运用这些工具,将有助于提高开发效率.增强代码质量.下面就最常用的Assert工具类,简要介绍一下它的用法.Assert ...
- C#高级语法
委托 委托就是指针函数,委托的定义与类的属性定义类似都必须在类的方法体进行. 委托的定义: class Program { //定义委托:委托不能在方法体内定义. public delegate st ...
- 【转】 Oracle 中的一些重要V$ 动态性能视图,系统视图和表
v$database:数据库的信息,如数据库名,创建时间等. v$instance 实例信息,如实例名,启动时间. v$parameter 参数信息,select * from v$parameter ...
- zk实现服务选举
非公平选举算法1)首先通过zk创建一个 /server 的PERSISTENT节点 2)多台机器同时创建 /server/leader EPHEMERAL子节点 3)子节点只能创建一个,后创建的会失败 ...
- 适配器模式和php实现
1. 概述 将一个类的接口转换成客户希望的另外一个接口.Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以在一起工作. 2. 解决的问题 即Adapter模式使得原本由于接口不兼容而不 ...
- vue2.0:(九)、外卖App弹窗部分星星评分
本篇是星星评分部分,先上代码: 1.header.vue: <template> <transition name="fade"> & ...
- 使用 h5 新特性,轻松监听任何 App 自带返回键
var hiddenProperty = 'hidden' in document ? 'hidden' : 'webkitHidden' in document ? 'webkitHidden' : ...
- Python+Selenium与Chrome如何进行完美结合
zhuan:http://blog.51cto.com/starpoint/2102975?cid=704621 使用WebDriver在Chrome浏览器上进行测试时,需要从http://chrom ...
- Hybrid框架安全隐患分析
Hybrid框架安全隐患分析 目前我司移动端项目中各种app如雨后春笋般生根发芽层出不穷.而利用Hybrid框架确实可以减轻一部分移动端压力.并且做到灵活发版.但是其中的安全问题往往让人忽略. 针对A ...
- BaseAdapter.notifyDataSetChanged()之观察者设计模式及源码分析
BaseAdapter.notifyDataSetChanged()的实现涉及到设计模式-观察者模式,详情请参考我之前的博文设计模式之观察者模式 Ok,回到notifyDataSetChanged进行 ...