Java之动态绑定与静态绑定

1、当子类和父类存在同一个方法,子类重写了父类的方法,程序在运行时调用方法是调用父类的方法还是子类的重写方法呢?
2、当一个类中存在方法名相同但参数不同(重载)的方法,程序在执行的时候该如何辨别区分使用哪个方法呢?
在Java中我们使用静态绑定(static binding)和动态绑定(Dynamic binding)来解决,那么什么是绑定?什么是静态绑定?什么又是动态绑定?有什么区别?

绑定、静态绑定、动态绑定的概念

  • 绑定

    绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。
    对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定。

  • 静态绑定

    在程序执行前方法已经被绑定,针对java简单的可以理解为程序编译期的绑定;
    java当中的方法只有final,static,private和构造方法是前期绑定

  • 动态绑定

    在运行时根据具体对象的类型进行绑定。提供了一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。

动态绑定的过程:
虚拟机提取对象的实际类型的方法表;
虚拟机搜索方法签名;
调用方法。

静态绑定 VS 动态绑定

1、静态绑定是发生在编译阶段;而动态绑定是在运行阶段;
2、private, final and static方法和变量使用静态绑定,而虚函数(virtual methods)则会根据运行时的具体对象进行绑定(注:在Java语言中, 所有的方法默认都是”虚函数”。只有以关键字 final 标记的方法才是非虚函数。)
3、静态绑定使用的是类信息,而动态绑定使用的是对象信息
4、重载方法(overloaded methods)使用的是静态绑定,而重写方法(overridden methods)使用的是动态绑定

下面从代码中分析

静态绑定

public class StaticBindingTest {

    public static void main(String args[])  {
        StaticBindingTest sbt = new StaticBindingTest();
        sbt.test("This is a String");
        sbt.test(10);
     }

    public void test(String s) {
        System.out.println(s);
    }

    public void test(int a) {
        System.out.println(a);
    }
}

输出结果

This is a String
10

从上面的结果可以得出:

在两个同名但参数不同的方法(重载),在调用方法sbt.test(param)时,程序会自动根据输入的参数类型来选择具体调用哪个方法,其后的原理就是静态绑定,即在编译期根据参数类型进行静态绑定。

java当中的向上转型或者说多态是借助于动态绑定实现的,所以理解了动态绑定,也就搞定了向上转型和多态。

动态绑定的典型发生在父类和子类的转换声明之下:

比如:Parent p = new Child();
其具体过程细节如下:
1:编译器检查对象的声明类型和方法名。假设我们调用p.method()方法,并且p已经被声明为Child类的对象,那么编译器会列举出Child类中所有的名称为method的方法和从Child类的父类继承过来的method方法
2:接下来编译器检查方法调用中提供的参数类型。如果在所有名称为method 的方法中有一个参数类型和调用提供的参数类型最为匹配,那么就调用这个方法,这个过程叫做“重载解析” 
3:当程序运行并且使用动态绑定调用方法时,虚拟机必须调用同p所指向的对象的实际类型相匹配的方法版本。假设child类定义了mehod()那么该方法被调用,否则就在child的父类(Parent类)中搜寻方法method()

动态绑定

子类有父类的重写方法
//父类
public class Parent {

    protected String name = "ParentName";

    public void method() {
        System.out.println("ParentMethod");
    }
}

//子类
public class Child extends Parent {
    protected String name = "ChildName";

    public void method() {
        System.out.println("ChildMethod");
    }

    public static void main(String[] args) {
        Parent p = new Child();
        System.out.println(p.name);
        p.method();
    }
}

输出结果

ParentName
ChildMethod
子类中没有父类的重写方法
//测试类
public class DynamicBindingTest {

    public static void main(String[] args) {
        Parent p = new Child();
        System.out.println(p.name);
        p.method();
    }
}

//父类
class Parent {

    protected String name = "ParentName";
    
    public void method() {
        System.out.println("ParentMethod");
    }
}

//子类
class Child extends Parent {
    protected String name = "ChildName";
    
}    

输出结果:

ParentName
ParentMethod

从上面的结果中可以看出:

1、子类的对象(由父类的引用handle)调用到的是父类的成员变量,运行时(动态)绑定针对的范畴只是对象的方法,而属性要采取静态绑定方法。
2、执行p.method()时会先去调用子类的method方法执行,若子类没有则向上转型去父类中寻找。
所以在向上转型的情况下,对象的方法可以找到子类,而对象的属性还是父类的属性。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,332评论 5 475
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,930评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,204评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,348评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,356评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,447评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,862评论 3 394
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,516评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,710评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,518评论 2 318
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,582评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,295评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,848评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,881评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,121评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,737评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,280评论 2 341

推荐阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,550评论 18 399
  • (一)Java部分 1、列举出JAVA中6个比较常用的包【天威诚信面试题】 【参考答案】 java.lang;ja...
    独云阅读 7,057评论 0 62
  • 程序绑定的概念: 绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动...
    Mr_chong阅读 1,352评论 0 7
  • 关于青春的演讲,陈昊篮说“如果有来生,我想和你倒着爱一次”,从争吵中放下行李箱到最初那一句你好。关于走...
    闫米MY阅读 1,318评论 0 0
  • 大家好!有没有朋友考虑过,去生产一些质量好,价格低商品呢?如果有我们可以在这里聊聊。我就是个卖牛仔裤的,别的行业不...
    80c8e16ee03a阅读 238评论 0 2