java动态静态_Java之动态绑定与静态绑定

1、java中有两个概念

a、动态绑定(后期绑定)

b、静态绑定(前期绑定)

2、简单说说定义

绑定:把一个方法与其所在的类或者实例对象关联起来叫做方法的绑定

动态绑定:程序运行时根据具体对象的类型进行绑定

静态绑定:程序运行前就确定该方法是属于哪个类的,在编译的时候就可以定位到这个方法

3、动态绑定

根据具体的实例对象才能具体确定是绑定的哪个方法

动态绑定是多态实现的重要因素,它通过一个方法表(位于方法区)来实现:每个类被加载到虚拟机时,在方法区保存元数据,其中,包括一个叫做 方法表(method table)的东西,表中记录了这个类定义的方法的引用,每个表中的元素指向一个具体的方法代码。如果这个类重写了父类中的某个方法,则对应表中的元素会指向新的代码实现处,从父类继承来的方法位于子类定义的方法的前面。

动态绑定语句的编译、运行原理:我们假设 Father ft=new Son();  ft.say();  Son继承自Father,重写了say()。

a、编译:我们知道,向上转型时,用父类引用指向子类对象,并可以用父类引用调用子类中重写了的方法。但是不能调用子类中新增的方法(子类独有的方法),这是为什么呢?

因为在代码的编译阶段,编译器通过 声明对象(变量)的类型(即引用本身的类型)在方法区中的该类型的方法表中查找匹配的方法(最佳匹配法:参数类型最接近的被调用),如果有则编译通过,没有则编译失败。这里是根据声明的对象类型来查找的,所以此处是查找 Father类的方法表,而Father类的方法表中是没有子类新增的方法的,所以不能是调用子类的独有的方法的

编译阶段是确保方法的存在性,保证程序能顺利、安全运行。

b、运行:我们又知道,ft.say()调用的是Son中的say(),这不就与上面说的,查找Father类的方法表的匹配方法矛盾了吗?不,这里就是动态绑定机制的真正体现

上面编译阶段在声明对象类型 的方法表中查找方法,只是为了安全地通过编译(也为了检验方法是否是存在的)。而在实际运行这条语句时,在执行 Father ft=new Son(); 这一句时创建了一个Son实例对象,然后在 ft.say() 调用方法时,JVM会把刚才的son对象压入【操作数栈】(位于栈帧中),用它来进行调用。而用实例对象进行方法调用的过程就是动态绑定:根据实例对象所属的类型去查找它的方法表,找到匹配的方法进行调用。我们知道,子类中如果重写了父类的方法,则方法表中同名的元素会指向子类的方法代码;若无重写,则按照父类中的方法表顺序保存在子类的方法表中。故此:动态绑定根据对象的类型的方法表查找方法是一定会匹配(因为编译时在父类方法表中以及查找并匹配成功了,说明方法是存在的。这也解释了为何向上转型时父类引用不能调用子类新增的方法:在父类方法表中必须先对这个方法的存在性进行检验,如果在运行时才检验就容易出危险——可能子类中也没有这个方法)

4、静态绑定

Java中,final、private、static修饰的方法以及构造函数都是静态绑定的,不需程序运行,不需具体的实例对象就可以知道这个方法的具体内容,他们统统属于静态绑定(无需动态绑定)

a、因为final方法不允许重写

b、private的方法也没法重写

c、static修饰的方法只有隐藏,也没有重写的概念

d、构造方法,隐式的就是static的,属于类的嘛

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值