Java中的绑定
1 前言
做了一次笔试题,发现了一题问答题,是关于Java绑定的:

当时做的时候是完全不会的。。。
于是这里补上一篇Java绑定的文章。
2 绑定
首先来了解一下绑定的概念。绑定是指一个方法的调用与方法所在的类关联起来。
很抽象吧,举个例子,如果父类与子类存在同名方法,子类对父类方法进行了重写,那么就需要绑定来区分调用的到底是父类的方法还是子类的方法。相对简单的一种理解是,绑定是一个方法的调用与调用这个方法的类连接在一起的过程。
而绑定具体又可以分为:
- 静态绑定:就是程序执行前,方法已经被绑定,可以简单理解成编译期绑定
- 动态绑定:在运行时根据具体对象的类型进行绑定,通过一些机制去运行时判断对象的类型,并分别调用适当的方法
3 静态绑定
静态绑定也叫前期绑定、编译期绑定,在程序运行之前,也就是编译时期JVM能够确认方法由谁调用,这种机制就叫静态绑定。
如果一个方法由private、static、final任意一个关键字修饰,那么这个方法就是静态绑定的,原因很简单,因为:
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中,所有的非final、private、static的方法都是动态绑定的,因为只要继承了就能重写。
5 区别
- 发生时期:静态绑定发生在编译时期,动态绑定发生在运行时期
- 灵活性:动态绑定的灵活性要比静态绑定高,因为静态绑定在编译的时期就确定了,而动态绑定在编译的时候并不知道是调用哪一个类的方法
- 速度:静态绑定调用方法的速度要快于动态绑定,因为静态绑定可以直接调用,而动态绑定需要去搜索方法表
6 动态绑定的过程
在了解动态绑定的过程之前,先了解一些前置知识。
6.1 方法调用
Java中的方法调用有两类:
- 静态方法调用
- 动态方法调用
而方法调用的指令有四个,分别是:
invokestaticinvokespecialinvokevirtualinvokeinterface
前两个是静态绑定的,而后两个是动态绑定的。
6.2 方法表
方法表是字节码文件的一部分,每个类都有一个方法表,方法表是为invokevirtual以及invokeinterface指令服务的。由于Java中的类都继承于Object,因此,在默认情况下,所有类的方法表中都有Object的方法,如果重写了其中的方法,就会改变其中的描述符。比如,Object类的方法表可以简单理解如下:

而加载了A类的字节码后,因为A类并没有重写任何的Object方法,因此只是添加了A类本身的方法:

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

6.3 具体过程
了解了前置知识后看具体过程就会相对简单一点了,动态绑定的过程可以分为三步:
- 虚拟机提取对象实际类型的方法表:
JVM获取到对象的实际类型后,再获取该类型的方法表 - 虚拟机搜索方法签名:当调用
b.print()时,通过方法表发现实际方法是B.print() - 调用方法:调用
B.print()
7 参考
Java中的绑定的更多相关文章
- ThreadLocal,Java中特殊的线程绑定机制
在DRP项目中,我们使用了ThreadLocal来创建Connection连接,避免了一直以参数的形式将Connection向下传递(传递connection的目的是由于jdbc事务要求确保使用同一个 ...
- 理解Java中的前期绑定和后期绑定
前期绑定,在程序执行前根据编译时类型绑定,调用开销较小,如C语言只有前期绑定这种方法调用. 后期绑定,是指在运行时根据对象的类型进行绑定,又叫动态绑定或运行时绑定.实现后期绑定,需要某种机制支持,以便 ...
- Java-ThreadLocal,Java中特殊的线程绑定机制
在DRP项目中,我们使用了ThreadLocal来创建Connection连接,避免了一直以参数的形式将Connection向下传递(传递connection的目的是由于jdbc事务要求确保使用同一个 ...
- 关于JAVA中的前期绑定 后期绑定(动态绑定)
前期绑定,在程序执行前根据编译时类型绑定,调用开销较小,如C语言只有前期绑定这种方法调用. 后期绑定,是指在运行时根据对象的类型进行绑定,又叫动态绑定或运行时绑定.实现后期绑定,需要某种机制支持,以便 ...
- Java中的Socket的用法
Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...
- Java中的泛型 (上) - 基本概念和原理
本节我们主要来介绍泛型的基本概念和原理 后续章节我们会介绍各种容器类,容器类可以说是日常程序开发中天天用到的,没有容器类,难以想象能开发什么真正有用的程序.而容器类是基于泛型的,不理解泛型,我们就难以 ...
- 浅谈Java中的equals和==(转)
浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...
- 浅谈Java中的equals和==
浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: String str1 = new String("hello"); String str2 = ...
- 深入理解Java中的final关键字
Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量,方法和类声明为final代表了什么?使用final的好处是什么?最后也有一些使 ...
随机推荐
- pycharm + git+gitlab的可视化界面操作
前言: 写这篇博客,主要为了记录一套经过本人实践,并运行通过的操作gitlab流程. 通过以下步骤,可实现最基本的远程服务器(gitlab)和本地工具(pycharm)的,针对两端文件增删改查的及 ...
- Python算法_整数反转(02)
给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转. 示例 1: 输入: 123输出: 321 示例 2: 输入: -123输出: -321 示例 3: 输入: 120 输出: 2 ...
- 树的遍历c/c++
先序遍历(递归) 1 void preOrderTraverase(TreeNode * r) 2 { 3 if(r) 4 { 5 printf("%d\t",r->_dat ...
- docker封装vue项目并使用jenkins发布
一.概述 vue项目可以打一个dist静态资源包,直接使用Nginx发布即可. 现在由于要上docker,需要将vue项目和nginx打成一个镜像才行. 项目结构如下: ./ ├── build │ ...
- Linux下搭建RocketMQ环境
Apache 官网: http://rocketmq.apache.org/ RocketMQ 的 Github 地址: English:https://github.com/apache/rocke ...
- POJ-3468(线段树+区间更新+区间查询)
A Simple Problem With Integers POJ-3468 这题是区间更新的模板题,也只是区间更新和区间查询和的简单使用. 代码中需要注意的点我都已经标注出来了,容易搞混的就是up ...
- HDOJ-1213(简单并查集)
How many tables HDOJ-1213 #include<iostream> #include<cstring> #include<cstdio> #i ...
- AI在出行场景的应用实践:路线规划、ETA、动态事件挖掘…
前言:又到春招季!作为国民级出行服务平台,高德业务快速发展,大量校招/社招名额开放,欢迎大家投递简历,详情见文末.为帮助大家更了解高德技术,我们策划了#春招专栏#的系列文章,组织各业务团队的高年级同 ...
- const修饰符相关
const修饰符相关 const修饰符表明一个变量是常量,大致分为三类:常量数组(等同于常量指针),常量指针,指向常量的指针. 常量数组中数据都是不可修改的,任何试图修改常量数组中的数据的操作都会报错 ...
- layui数据表格-通过点击按钮使数据表格中的字段值增加
通过点击右侧相对应的操作按钮,对迟到.休假次数实现自增效果 jsp页面代码 //监听行工具事件 table.on('tool(test)', function(obj){ var data = obj ...