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 ...
随机推荐
- Dell服务器安装系统中遇到的坑
在本学期开学初期,由于后续实验的需要,老师为我们配置了服务器,该服务器的型号为Dell Power R730. 由于我也是一个小白,在服务器安装系统的过程中,遇到了一些麻烦,在这里记录下来,希望自己能 ...
- JS中比较的数值如何比较大小
<script type="text/javascript"> function check_num(){ var num=document.getElementByI ...
- Error resolving template: template might not exist or might not be accessible是一句缩水报错?
一 thymeleaf在开发的时候本地调试正常,但是在测试环境打成jar包就报这个错误了. 二 template might not exist or might not be accessible ...
- Typora--Draw Diagrams With Markdown
Typora Typora supports some Markdown extension for diagrams, you could enable this feature from pref ...
- WPF (VisualChildren)可视化子元素详解
VisualChildrenCount 的 FrameworkElement 实现始终返回 0 或 1. 如果类所要维护的可视化子元素集合的成员数可能超过 1,则这样的类必须重写此属性和 Ge ...
- Spring Aspect 获取请求参数
切片(Aspect)也就是Spring AOP 实现Aspect的主要步骤: 1.在哪里切入 .在哪个方法起作用 .什么时候起作用 2.起作用的时候执行什么处理逻辑 下面是代码实现 /** * 切片A ...
- https的网站使用百度地图的问题
https的网站使用百度地图,如果你引用的地址没写对的话,加载不出来百度地图,被认为是不安全的JS内容. 引用的地址:http://api.map.baidu.com/api?v=2.0&ak ...
- .NET easyUI tree树状结构
简单的制作后台制作写一个json(string类型)格式 public partial class goodstype_type : System.Web.UI.Page { public strin ...
- java入门第二章——java编程基础
习题 一.填空题 (p)1.java中的程序代码都必须在一个类中定义,类使用(class)关键字来定义. (p)2.布尔常量即布尔类型的两个值,分别是(true)和(false) (p18)3.jav ...
- codeforce Gym 100500F Door Lock (二分)
根据题意略推一下,其实就是问你满足(a*(a+1))/2 < m <= ((a+1)*a(a+2))/2的a和m-(a*(a+1))/2 -1是多少. 二分求解就行了 #include&l ...