关于java:Java中的绑定

45次阅读

共计 1733 个字符,预计需要花费 5 分钟才能阅读完成。

1 前言

做了一次口试题,发现了一题问答题,是对于 Java 绑定的:

过后做的时候是齐全不会的。。。

于是这里补上一篇 Java 绑定的文章。

2 绑定

首先来理解一下绑定的概念。绑定是指 一个办法的调用与办法所在的类关联起来

很形象吧,举个例子,如果父类与子类存在同名办法,子类对父类办法进行了重写,那么就须要绑定来辨别调用的到底是父类的办法还是子类的办法。绝对简略的一种了解是,绑定是一个办法的调用与调用这个办法的类连贯在一起的过程。

而绑定具体又能够分为:

  • 动态绑定:就是程序执行前,办法曾经被绑定,能够简略了解成编译期绑定
  • 动静绑定:在运行时依据具体对象的类型进行绑定,通过一些机制去运行时判断对象的类型,并别离调用适当的办法

3 动态绑定

动态绑定也叫后期绑定、编译期绑定,在程序运行之前,也就是编译期间 JVM 可能确认办法由谁调用,这种机制就叫动态绑定。

如果一个办法由 privatestaticfinal 任意一个关键字润饰,那么这个办法就是动态绑定的,起因很简略,因为:

  • private润饰的办法,无奈由本类以外的类调用,也就是调用者只能是该类
  • static润饰的办法,通过 类名. 办法名 进行调用,也能够惟一确定了调用的类
  • final润饰的办法,不能被子类进行重写,在编译期就能确定了调用的类

这三个关键字润饰的办法,都能够在编译期间就能惟一确定了调用的类,不存在子类调用的问题,因而应用动态绑定,而不是动静绑定。

4 动静绑定

动静绑定就是运行时依据对象的类型进行绑定,简略来说,JVM在运行期间决定由哪个对象调用的过程称为动静绑定。

比方:

public class Main {public static void main(String[] args){A b = new B();
        b.print();}
}

class A{public void print(){System.out.println("A");
    }
}

class B extends A{
    @Override
    public void print(){System.out.println("B");
    }
}

因为 B 类继承了 A 类,因而创建对象的时候:

A b = new B();

编译期并不知道 b 真正援用的是 A 类还是 B 类,在运行的时候才晓得 b 是一个 A 类对象,然而指向了 B 类的援用。

Java 中,所有的非 finalprivatestatic 的办法都是动静绑定的,因为只有继承了就能重写。

5 区别

  • 产生期间:动态绑定产生在编译期间,动静绑定产生在运行期间
  • 灵活性:动静绑定的灵活性要比动态绑定高,因为动态绑定在编译的期间就确定了,而动静绑定在编译的时候并不知道是调用哪一个类的办法
  • 速度:动态绑定调用办法的速度要快于动静绑定,因为动态绑定能够间接调用,而动静绑定须要去搜寻办法表

6 动静绑定的过程

在理解动静绑定的过程之前,先理解一些前置常识。

6.1 办法调用

Java中的办法调用有两类:

  • 静态方法调用
  • 动静办法调用

而办法调用的指令有四个,别离是:

  • invokestatic
  • invokespecial
  • invokevirtual
  • invokeinterface

前两个是动态绑定的,而后两个是动静绑定的。

6.2 办法表

办法表是字节码文件的一部分,每个类都有一个办法表,办法表是为 invokevirtual 以及 invokeinterface 指令服务的。因为 Java 中的类都继承于 Object,因而,在默认状况下,所有类的办法表中都有Object 的办法,如果重写了其中的办法,就会扭转其中的描述符。比方,Object类的办法表能够简略了解如下:

而加载了 A 类的字节码后,因为 A 类并没有重写任何的 Object 办法,因而只是增加了 A 类自身的办法:

而加载了 B 类的字节码后,因为重写了print(),因而办法表如下:

6.3 具体过程

理解了前置常识后看具体过程就会绝对简略一点了,动静绑定的过程能够分为三步:

  • 虚拟机提取对象理论类型的办法表:JVM获取到对象的理论类型后,再获取该类型的办法表
  • 虚拟机搜寻办法签名:当调用 b.print() 时,通过办法表发现理论办法是B.print()
  • 调用办法:调用B.print()

7 参考

  • StackOverflow-How does dynamic binding happens in JVM?
  • 博客园 -Java 多态实现原理

正文完
 0