专栏首页Java建设者理解静态绑定与动态绑定

理解静态绑定与动态绑定

一个Java 程序要经过编写、编译、运行三个步骤,其中编写代码不在我们讨论的范围之内,那么我们的重点自然就放在了编译 和 运行这两个阶段,由于编译和运行阶段过程相当繁琐,下面就我的理解来进行解释:

Java程序从源文件创建到程序运行要经过两大步骤:

1、编译时期是由编译器将源文件编译成字节码的过程

2、字节码文件由Java虚拟机解释执行

绑定

绑定就是一个方法的调用与调用这个方法的类连接在一起的过程被称为绑定

绑定分类

绑定主要分为两种:

静态绑定 和 动态绑定

绑定的其他叫法

静态绑定 == 前期绑定 == 编译时绑定

动态绑定 == 后期绑定 == 运行时绑定

为了方便区分: 下面统一称呼为静态绑定和动态绑定

静态绑定

在程序运行前,也就是编译时期JVM就能够确定方法由谁调用,这种机制称为静态绑定

识别静态绑定的三个关键字以及各自的理解

如果一个方法由private、Static、final任意一个关键字所修饰,那么这个方法是前期绑定的

构造方法也是前期绑定

private:private关键字是私有的意思,如果被private修饰的方法是无法由本类之外的其他类所调用的,也就是本类所特有的方法,所以也就由编译器识别此方法是属于哪个类的

public class Person {
    private String talk;
    private String canTalk(){        return talk;    }}
class Animal{
    public static void main(String[] args) {        Person p = new Person();        // private 修饰的方法是Person类独有的,所以Animal类无法访问(动物本来就不能说话)//        p.canTalk();    }}

final:final修饰的方法不能被重写,但是可以由子类进行调用,如果将方法声明为final可以有效的关闭动态绑定

public class Fruit {
    private String fruitName;
    final String eatingFruit(String name){        System.out.println("eating " + name);        return fruitName;    }}
class Apple extends Fruit{
      // 不能重写final方法,eatingFruit方法只属于Fruit类,Apple类无法调用//    String eatingFruit(String name){//        super.eatingFruit(name);//    }
    String eatingApple(String name){        return super.eatingFruit(name);    }}

static: static修饰的方法比较特殊,不用通过new出某个类来调用,由类名.变量名直接调用该方法,这个就很关键了,new 很关键,也可以认为是开启多态的导火索,而由类名.变量名直接调用的话,此时的类名是确定的,并不会产生多态,如下代码:

public class SuperClass {
    public static void sayHello(){                System.out.println("由 superClass 说你好");    }}
public class SubClass extends SuperClass{
    public static void sayHello(){        System.out.println("由 SubClass 说你好");    }
    public static void main(String[] args) {        SuperClass.sayHello();        SubClass.sayHello();    }}

SubClass 继承SuperClass 后,在

是无法重写sayHello方法的,也就是说sayHello()方法是对子类隐藏的,但是你可以编写"自己的"sayHello()方法,也就是子类SubClass 的sayHello()方法,由此可见,方法由static 关键词所修饰,也是编译时绑定

动态绑定

概念

在运行时根据具体对象的类型进行绑定

除了由private、final、static 所修饰的方法和构造方法外,JVM在运行期间决定方法由哪个对象调用的过程称为动态绑定

如果把编译、运行看成一条时间线的话,在运行前必须要进行程序的编译过程,那么在编译期进行的绑定是前期绑定,在程序运行了,发生的绑定就是后期绑定

代码理解

public class Father {
    void drinkMilk(){        System.out.println("父亲喜欢喝牛奶");    }}
public class Son extends Father{
    @Override    void drinkMilk() {        System.out.println("儿子喜欢喝牛奶");    }
    public static void main(String[] args) {        Father son = new Son();        son.drinkMilk();    }}

Son类继承Father类,并重写了父类的dringMilk()方法,在输出结果得出的是儿子喜欢喝牛奶。那么上面的绑定方式是什么呢?

上面的绑定方式称之为动态绑定,因为在你编写 Father son = new Son()的时候,编译器并不知道son对象真正引用的是谁,在程序运行时期才知道,这个son是一个Father类的对象,但是却指向了Son的引用,这种概念称之为多态,那么我们就能够整理出来多态的三个原则:

1. 继承

2.重写

3.父类对象指向子类引用

也就是说,在Father son = new Son() ,触发了动态绑定机制。

动态绑定的过程

  1. 虚拟机提取对象的实际类型的方法表;
  2. 虚拟机搜索方法签名;
  3. 调用方法。

动态绑定和静态绑定的特点

静态绑定

静态绑定在编译时期触发,那么它的主要特点是

1、编译期触发,能够提早知道代码错误

2、提高程序运行效率

动态绑定

1、使用动态绑定的前提条件能够提高代码的可用性,使代码更加灵活。

2、多态是设计模式的基础,能够降低耦合性。

参考: https://blog.csdn.net/zhangjk1993/article/details/24066085

本文分享自微信公众号 - Java建设者(javajianshe),作者:cxuan

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-03-04

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 硬核原创|Java 面试题全梳理

    要想真正理解的话,可以参考这篇文章 :https://www.zhihu.com/question/31203609

    cxuan
  • 看完这篇Exception 和 Error,和面试官扯皮就没问题了

    在 Java 中的基本理念是 结构不佳的代码不能运行,发现错误的理想时期是在编译期间,因为你不用运行程序,只是凭借着对 Java 基本理念的理解就能发现问题。但...

    cxuan
  • 对于spring mvc中post、get方法获取参数的的几种方式,你了解多少?

    get与post两种方式的区别:对于本文主题而言,最显著的区别就是get请求方式参数是在url后,而post请求方式的参数是在request body中。因此两...

    cxuan
  • SpringMVC:数据绑定入门(-)

    1.数据类型,可以绑定基本数据类型,如int age,或者包装类型如:Integer age;

    Dar_Alpha
  • Mac开发之 Cocoa 绑定 入门

    从iOS开发转为Mac OSX应用开发的过程中,cocoa 绑定算是比较大的一个差异,也是OSX上比较实用的技术,cocoa 绑定让开发者节省了大量的代码,可以...

    代码行者
  • 2019-2-13-wcf入门(15)

    绑定是用于配置wcf如何进行endpoint的对象,其包括协议配置(如2019-2-12-wcf入门(14) - huangtengxiao用到的可靠会话配置)...

    黄腾霄
  • WPF 笔刷绑定不上可能的原因

    在 WPF 中如背景色等都是使用笔刷,在使用绑定的时候可能绑定不上,本文告诉大家绑定不上可能的原因和调试方法

    林德熙
  • QML教程-属性绑定与赋值

    Qt君
  • WCF系统内置绑定列表与系统绑定所支持的功能

    莫问今朝
  • [WCF 4.0新特性] 默认绑定和行为配置

    对于传统的WCF配置系统,无论是绑定的配置还是行为(服务行为和终结点行为)都必须具有一个名称。而正是通过整个配置名称,它们才能被应用到目标对象(终结点或者服务)...

    蒋金楠

扫码关注云+社区

领取腾讯云代金券