zoukankan      html  css  js  c++  java
  • 前期绑定 和 后期绑定

    thinking in java 读书笔记(感悟);
    页码:P9 (想看书上怎么讲的。自行翻看 P9 页)
    
    写于:2018年3月29日19:22:14
    
    作者:淮左白衣
    

    目录


    场景:

     public void eat(Animal animal){
            System.out.println(animal.eatSometing());
        }
    
        ....
        ....
    
        Dog dog = new Dog();
        eat(dog);
        Cat cat = new Cat();
        eat(cat);

    一眼就可以看出,这是多态;在多态的时候,我们将子类的类型向上转型为父类,进行类型的泛化,便于我们写出实用性很强的代码(新类型产生,不用修改原有代码);
    就像这里 eat 方法,接受一个 Animal类型 ;我们传进去的分别是 dogcat ;但是打印出的结果是明确的,传dog进去,输出狗吃骨头,传cat进去,输出猫吃鱼
    但是这里有个问题,不知道大家想过没有:任何类型传进去,都是父类型,但是在调用方法的时候,却是明明确确的调用了子类的方法!或者 编译器是怎么知道,具体该调用哪一个方法的呢?
    这就是本文要讲的 前期绑定后期绑定


    前期绑定

    前期绑定是 面向过程 语言的编译器的做法 ;编译器在 编译 面向过程语言的时候,在出现 函数调 用的时候,会产生一个 对具体函数名字的引用 ,这样在程序运行的时候,执行到函数调用的语句,就会发现这里一个 对XXX方法的引用,就会把执行逻辑解析到这个XXX方法的绝对地址上;

    但是这一套,到java这就不好使了,编译器在编译代码的时候,知道具体调用哪一个方法吗?编译器不是神,它不可能知道的;

    因此,我们需要另谋蹊径,伟大的计算机科学家,想到了 后期绑定


    后期绑定

    既然编译时期,编译器搞定不了方法调用的问题!那么,就在运行期,做手脚,来搞定这件事;

    java是这样来搞定方法调用的在每一个对象中存储一小段信息,通过这一小段信息,可以计算出该对象的方法地址 ;然后去调用方法

    因此上述代码的调用就可以得到理解:虽然传进去的都是 Animal引用但是引用指向的对象是Dog、Cat对象,这个对象里面保存了信息;比如Dog对象,里面就保存它的eatSomething方法在哪里 ;这样虚拟机就会调用正确的方法了 ;


    顺便讲下 编译看左边,运行看右边 的背后是什么意思吧 ;

    编译看左边,运行看右边

    这句话,好多人都知道的,但是为什么呢
    

    其实这就是后期绑定的原因 ;java的编译器,虽然在编译期间不能为方法调用做些什么,但是也不能啥也不干吧 ;(它要是不干了,虚拟机可能就不开心了,凭啥都是我在做事呀o(╥﹏╥)o) ;

    java的编译器在编译期间,会检查这个要调用的方法是否存在,调用的参数是否正确 ;返回的类型是否正确;简单说,就是做一些检查工作 ;

    这个检查工作,就是为什么编译看左边;假如父类没有这个方法,编译时过不去的,因为编译器对方法是否存在进行检查;运行看右边,是因为后期绑定,去调用具体的方法了 ;


  • 相关阅读:
    怎么看待MYSQL的性能
    java dom4j 读写XML
    cas4.2的安装
    java websocket
    解决openresty http客户端不支持https的问题
    开源许可证GPL、BSD、MIT、Mozilla、Apache和LGPL的区别
    SpringMVC框架的学习(一):初步认识
    Spring框架: 理解为它是一个管理对象的创建,依赖,销毁的容器。
    Springmvc如何进行异常处理
    Springmvc:注解有哪些。
  • 原文地址:https://www.cnblogs.com/young-youth/p/11665746.html
Copyright © 2011-2022 走看看