Java动态绑定的细节

首先,存在一些从来不能使用动态绑定的情况。
  • 静态方法:不管这个办法怎么被调用
  • 最终方法
  • 私有方法(因为它们只能从类的内部被调用,因此是隐式的最终方法)

动态绑定意味着:目前正在调用的方法正是最适用于要操作对象的那个方法。然而它并不意味着对所有的参数都执行最佳匹配。
在Java中,一个方法的参数在编译阶段常被静态地绑定。

一个例子:
class Base{
    public void foo(Base x){
        System.out.println("Base.Base");
    }
    
    public void foo(Derived x){
        System.out.println("Base.Derived");
    }
}
 

class Derived extends Base{
  public void foo(Base x){
        System.out.println("Derived.Base");
    }
    
    public void foo(Derived x){
        System.out.println("Derived.Derived");
    }
}
 

class Main{
    public static void whichFoo(Base arg1, Base arg2){
        arg1.foo(arg2);
    }

    public static void main(String[] args)}{
        Base b = new Base();
        Derived d = new Derived();
    
        whichFoo(b,b);
        whichFoo(b,d);
        whichFoo(d,b);
        whichFoo(d,d);            
    }
}
 

因为 参数通常在编译阶段被匹配,在whichFoo方法中,形式参数arg2的类型是Base, 因此不管arg2实际引用的是什么类型,arg1.foo(arg2)匹配的foo都将是:
public void foo(Base x)

惟一的问题在于用Base还是Derived版本中的foo(Base x)函数?当知道arg1引用的对象时, 这是在运行阶段要决定的。

精确使用的方法是 编译器绑定,在编译阶段,最佳方法名依赖于参数的静态和控制引用的静态类型所适合的方法。在这一点上,设置方法的名称,这一步叫 静态重载
决定方法是哪一个类的版本,这通过由虚拟机推断出这个对象的 运行时类型来完成,一旦知道运行时类型,虚拟机就唤起继承机制,寻找方法的最终版本。这叫做 动态绑定

在方法whichFoor的调用arg1.foo(arg2),将根据arg1的运行时类型是Base还是Derived来调用Base类或者Derived类中的foo(Base x)版本函数。

由此理解方法的 覆盖重载。重载函数的实际调用版本由编译器绑定决定,而覆盖函数的实际调用版本由动态绑定决定。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值