zoukankan      html  css  js  c++  java
  • Java中的绑定

    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 参考

  • 相关阅读:
    VC++使用socket进行TCP、UDP通信实例总结
    [Android Pro] 调用系统相机和图库,裁剪图片
    [Android Pro] 查看 keystore文件的签名信息 和 检查apk文件中的签名信息
    [Android 新特性] 谷歌发布Android Studio开发工具1.0正式版(组图) 2014-12-09 09:35:40
    [Android 新特性] 有史来最大改变 Android 5.0十大新特性
    [Android Pro] service中显示一个dialog 或者通过windowmanage显示view
    [Android Pro] 通过Android trace文件分析死锁ANR
    [Android Memory] Android 的 StrictMode
    [Android Memory] Android性能测试小工具Emmagee
    [Android Memory] Android内存管理、监测剖析
  • 原文地址:https://www.cnblogs.com/6b7b5fc3/p/14642463.html
Copyright © 2011-2022 走看看