JAVA调用对象方法的执行过程:

①.编译器查看对象的声明类型和方法名。假设调用x.f(parameter),  且隐式参数x声明为C类型的对象,有可能在C对象中存在多个参数类型和参数个数不同的f的方法{例如:f(int)、f(int,String)和f(String)},编译器会一一列举C类中的f方法和C的超类中声明为public所有的f方法。

至此,编译器已经获得所有可能被调用的候选方法。

②.接下来,编译器将查看调用方法时所提供的参数类型和参数个数。如果所有名为f的方法中存在这样一个与提供方法的参数类型和参数个数完全匹配的方法,就选择这个方法,这个过程也称重载解析。例如:对于调用f(“This is my java”)来说,编译器会寻找f(String)这个方法。如果编译器没有找到与参数类型和参数个数匹配的方法,或者经过类型转换后有多个方法于此匹配,就会报告一个错误。

至此,已经寻找到需要调用的方法和参数类型

③.如果是此方法是被private、static、final修饰或则是构造器,那么编译器可以准确的知道应该调用哪个方法,于是便调用这个的方法。这种调用方式叫着静态绑定。静态绑定方式于此结束。

而与此对应是,调用方法依赖于隐式参数的实际类型,并且在运行时实现动态绑定,编译器采用动态绑定的方式会生成一条调用f(String)的指令(其原因请查看下面的动态绑定解析)。

④.当程序运行,并且采用动态绑定调用方法时,虚拟机一定调用与x所引用的对象的实际类型最适合的那个方法。假设x的实际类型是D,D是C的子类,如果D类定了方法f(String),编译器就直接调用它,否则就在D类的超类C中寻找f(String)方法,如果C类型中不存在这个方法,则又到寻找C的超类中寻找这个方法,以此类推。这个过程就称为动态绑定。

动态绑定解析:

每次调用方法时都要进行搜索,这样一来,时间开销相当大。因此,虚拟机预先为每一个类创建了一个方法表,其中列举出了类中的所有方法签名和实际调用的方法。而在真正调用方法的时候,虚拟机仅仅查找这个表就行了。在前面的列子中,虚拟机搜索D类的方法表。以便寻找与调用f(String)相匹配的方法。这个方法既可能是D.f(String),也可能是C.f(String),还有可能是*.f(String),这里的*是指D的超类。

----参考于《Core Java》

下面我们就举一个简单的例子:

新建一个Father类,并且让Son类继承Father基类:

package com.bin.bind;

public class TestBind {

public static void main(String[] args) {

String name = "TOM";

String hobby = "~~~sleep~~~";

int age = 19;

Father father = new Son(name, hobby, age);

String result = father.getAllInfo();

System.out.println(result);

}

}

class Father {

public Father(String name, int age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public int getAge() {

return age;

}

public void setName(String name) {

this.name = name;

}

public void setAge(int age) {

this.age = age;

}

public String getAllInfo() {

return "姓名是:"+this.name+"\t年龄是:"+this.age;

}

private String name = null;

private int age = 0;

}

class Son extends Father {

public Son(String name, String hobby, int age) {

super(name, age);

setHobby(hobby);

}

public String getHobby() {

return hobby;

}

public void setHobby(String hobby) {

this.hobby = hobby;

}

public String getAllInfo() {

return "姓名是:"+super.getName()+"\t年龄是:"+

super.getName()+"\t爱好是:"+hobby;

}

private String hobby = null;

}

在Father和Son类中都存在getAllInfo()这个方法,因为getAllInfo()不是static、final、private、构造方法,所以此方法将采用动态绑定。

在程序执行的时候虚拟机会为这个两个类生成方法表

Father类:

Father(String,int)->Father(String,int)

setAge(int)->Father.setAge(int)

getAge()->Father.getAge()

setName(String)->Father.setName(String)

getName()->Father.getName()

getAllInfo()->Father.getAllInfo()

Son类:

Father(String,int)->Father(String,int)

setAge(int)->Father.setAge(int)

getAge()->Father.getAge()

setName(String)->Father.setName(String)

getName()->Father.getName()

getAllInfo()->Father.getAllInfo()

Son(String,String,age)->Son(String,String,age)

setHobby(String)->Son.setHobby(String)

getHobby()->Son.getHobby()

getAllInfo()->Son.getAllInfo()

注意:上面列举的方法并不完整,因为他们还都默认继承了一个Object超类。

下面分析这条语句:

String result = father.getAllInfo();

father.getAllInfo()的解析过程如下:

①:虚拟机提取father类的实际类型的方法表。既可能是Father类也可能是Son类。(因为这里father引用所指向的是Son类的实例对象,所以实际类型必定是Son)

②:接下来,虚拟机搜索定义getAllInfo签名的类,此时,虚拟机已经知道调用哪个方法。(Son中只有一个getAllInfo方法,且与此匹配,所以被调用) ③:虚拟机执行调用方法。(最后将返回结果赋值给result)

java 调用对象的方法_JAVA调用对象方法的执行过程相关推荐

  1. java判断空对象为空_Java判断对象是否为空(包括null ,)的方法

    本文实例为大家分享了Java判断对象是否为空的具体代码,供大家参考,具体内容如下 package com.gj5u.publics.util; import java.util.List; /** * ...

  2. java中对象的生存期_Java中对象的生存周期

    文章目录 JAVA对象的生存周期 1.创建阶段(Created) 为对象分配内存需要考虑的问题 2.应用阶段(In Use) 3.不可见阶段(Invisible) 4.不可达阶段(Unreachabl ...

  3. java访问对象的属性_java访问对象的属性和行为详细介绍

    每一个对象都会有属于自己的属性和行为,下面的文章就对java访问对象的属性和行为做了一下详细的介绍. 对象的属性和行为在类当中体现为成员变量和成员方法,其中成员变量对应对象的属性,成员方法对应对象的行 ...

  4. java map对象排序输出_java实现对象的排序(List和Map)

    java实现对象的排序(List和Map) List和Map的排序 在实际的开发当中,我们经常 在文件浏览的时候经常有多种浏览方式,按时间整箱排序,逆向排序,按大小正逆向排序 ,按 按价格正逆向排序, ...

  5. java调c的接口_Java调用C接口的简单示例

    Java调用C接口的简单示例 正好需要用到Java调用dll里的C接口,想到自己做个简单的例子.我们可能需要自己生成dll文件,下边介绍一下,详细的步骤.主要参考https://blog.csdn.n ...

  6. java判断是否是数组_java判断对象是否是数组

    1.从构造函数入手,obj instanceof Array typeof 和 instanceof 都可以用来判断变量,typeof方法返回一个字符串,来表示数据的类型; 但是typeof来判断数据 ...

  7. c调用其他类的方法_Java 的 Native 方法——今天又进步了

    1. 简介 1.1 个人理解 初次遇见 native 是在 java.lang.String 源码中的一个 intern 方法: public native String intern(); 因为还是 ...

  8. java input是关键字吗_Java中对象的串行化(Serialization)和transient关键字 - 金色阳光...

    Java中对象的串行化(Serialization)和transient关键字: 对象的串行化(Serialization) 一.串行化的概念和目的 1.什么是串行化 对象的寿命通常随着生成该对象的程 ...

  9. java调用python项目实战_Java调用Python

    今天遇到Java调用一个Python脚本的问题,纠结了大半天,遇到各种问题.网上搜索的大部分都是用jython,但是我想要调用的python脚本里有import urllib,这个urllib也不是什 ...

最新文章

  1. php按条件修改xml,php如何修改xml内容
  2. API接口自动化之2 处理http请求的返回体,对返回体做校验
  3. Android开发常用开源框架:图片处理
  4. “面试不败计划”:集合知识整体总结
  5. VC++新建选择卡的解释
  6. P多行溢出省略号的处理
  7. 16岁上大学,25岁博士毕业,她还是南大医学院最年轻的博导!
  8. python flask restful api_python之restful api(flask)获取数据
  9. 无根树的同构:Hash最小表示法(bzoj 4337: BJOI2015 树的同构)
  10. 【python】函数和模块
  11. 屁屁岚分析开源项目3——贴片机飞达控制板
  12. css3立方体3d旋转,纯css3实现的3D立体动态旋转立方体特效
  13. 建筑业加速提高智能建造水准
  14. szszszszsz
  15. js贷款还款计算:等额本金、等额本息、先息后本、等本等息
  16. Apifox:详细使用教程,带你轻松拿捏
  17. 哈密瓜水果的文案,水果哈密瓜文案高级感
  18. UE4关于材质的几个小技巧
  19. 椭圆曲线ECC倍点运算forJava
  20. NetLogo基础代码

热门文章

  1. Spark精华问答 | Spark做大规模高性能数值计算可以吗?
  2. Mongo 安装、配置、启动 Windows
  3. 企业实战_08_MyCat 搭建Mysql 一主二从复制环境
  4. Springboot2.x +JPA 集成 Apache ShardingSphere 读写分离
  5. 03_SpringCloud整合Ribbon实现负载均衡
  6. angular图片上传
  7. greenplum配置高可用_高可用hadoop集群配置就收藏这一篇,动手搭建Hadoop(5)
  8. apache ant 安装_Jmeter+ Ant+jenkins 接口自动化框架实现
  9. 使用gitlab初次上传代码
  10. php 二维数组排序函数,php自定义函数实现二维数组排序功能