Java的静态绑定与动态绑定

2023-10-26

我们可以对思考一个问题:

JVM是如何知道调用的是哪个类的方法源代码? 这里面到底有什么内幕呢?

这篇文章我们就将揭露JVM方法调用的静态(static binding) 动态绑定机制(auto binding)

理解这两个绑定之前,我们不妨先理解一下绑定一词。

何为绑定?

在Java中绑定指的是一个方法的调用与方法所在的类(方法主体)关联起来。

在Java中的绑定有分为静态绑定和动态绑定;或者说叫前期绑定或者说后期绑定。

静态绑定

程序执行前方法已经被绑定,针对Java简单的可以理解为程序编译期的绑定;

这句话是什么意思呢?也就是在编译的时候我们就知道这个方法是哪个类对应的方法。

正对Java当中的方法只有final,static,private和构造方法是前期绑定。

我们可以简单写两个Demo:

public class Father {
    public static final void f1(){
        System.out.println("Father-f1()");
    }
}
public class StaticCall {
    public static void main(String[] args) {
        Father.f1();
    }
}

我们简单的对字节码文件做个分析(这里强力推荐一个IDEA看字节码的插件jclasslib)

 我们可以看出在对应第一行中的JVM将f1()这个方法通过invokespecial放入了常量池中,然后在Father类所在的方法区中找到f1()方法的直接地址,并将这个直接地址记录到StaticCall类的常量池中的常量表中。这个过程叫常量池解析 ,以后再次调用Father.f1()时,将直接找到f1方法的字节码。

通过上面的过程,我们发现经过常量池解析之后,JVM就能够确定要调用的f1()方法具体在内存的什么位置上了。实际上,这个信息在编译阶段就已经在StaticCall类的常量池中记录了下来。这种在编译阶段就能够确定调用哪个方法的方式,我们叫做静态绑定机制 。

除了被static 修饰的静态方法,所有被private 修饰的私有方法、被final 修饰的禁止子类覆盖的方法都会被编译成invokestatic指令。另外所有类的初始化方法<init>和<clinit>会被编译成invokespecial指令。JVM会采用静态绑定机制来顺利的调用这些方法。

final:final方法虽然可以被继承,但不能被重写(覆盖),虽然子类对象可以调用,但是调用的都是父类中所定义的那个final方法,(由此我们可以知道将方法声明为final类型,一是为了防止方法被覆盖,二是为了有效地关闭java中的动态绑定)。

private:对于private的方法,首先一点它不能被继承,既然不能被继承那么就没办法通过它子类的对象来调用,而只能通过这个类自身的对象来调用。因此就可以说private方法和定义这个方法的类绑定在了一起。

动态绑定

也就是在运行时的时候对对象进线绑定。

在运行时根据具体对象的类型进行绑定。提供了一些机制,可在运行期间判断对象的类型,并分别调用适当的方法。也就是说,编译器此时依然不知道对象的类型,但方法调用机制能自己去调查,找到正确的方法主体。

其实什么时候需要用到我们的动态绑定呢?也就是说什么时候我们需要运行时来进行对象的绑定的,我们不难想出在继承的时候。需要我们做出动态绑定。

因为当我们使用一个子类的时候,子类的方法如果发生覆盖,那么此时我们方法的绑定就要做一个换绑,这个其实也是我们Java中多态的一种体现方式。

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java的静态绑定与动态绑定 的相关文章

  • 如何查看JVM中JIT编译的代码?

    有什么方法可以查看 JVM 中 JIT 生成的本机代码吗 一般用法 正如其他答案所解释的 您可以使用以下 JVM 选项运行 XX UnlockDiagnosticVMOptions XX PrintAssembly 根据特定方法进行过滤 您
  • M1 Apple Silicon Mac 上的 Dynamodb 本地设置

    我使用 dynamodb 进行了本地设置https docs aws amazon com amazondynamodb latest developerguide DynamoDBLocal DownloadingAndRunning h
  • Java节流机制

    Update 我使用的是 Java 1 6 34 没有机会升级到 Java 7 我有一个场景 每分钟只允许调用一个方法 80 次 它实际上是由第 3 方编写的服务 API 如果调用次数过多 它会 关闭 忽略调用 其 API public c
  • Java应用程序cpu负载过高的解决办法

    今天 我发现我的服务器的cpu负载太高 并且服务器只运行一个Java应用程序 下面是我的操作步骤 I used top命令查找应用程序的 pid pid是25713 I used top H p 25713命令查找一些使用最多 cpu 的
  • hbase api - 通过行ID列表获取数据行信息

    是否可以通过hbase java API通过行id列表获取hbase数据记录 例如 我有一个已知的 hbase 行 ID 列表 mykey1 myhash1 mykey1 myhash2 mykey1 myhash3 mykey2 myha
  • 查找 Java Enum 的最佳实践

    我们有一个 REST API 客户端可以提供代表服务器上 Java 枚举中定义的值的参数 所以我们可以提供一个描述性错误 我们添加这个lookup每个枚举的方法 看起来我们只是在复制代码 不好 有更好的做法吗 public enum MyE
  • 配置 Sonar 以从 Maven pom.xml 中排除文件

    我有一个在maven中配置的项目 代码分析是由SonarQube完成的 我正在尝试在 pom xml 文件中配置 SonarQube 以从代码分析中排除一些文件 这些文件可以通过它们的类名来识别 它们在扩展名之前包含下划线字符 它们是元模型
  • 初始化类和实例化对象之间的区别?

    我尝试通过搜索引擎搜索这个问题 但可以找到一个主题来解释初始化类和实例化对象之间的区别 有人可以解释一下它们有何不同吗 与该主题相关的三个术语是 声明 初始化和实例化 从后到前工作 实例化 这是为对象分配内存的时候 这就是new关键字正在做
  • 如何实现 hamcrest 匹配器

    我想运行这行代码 assertThat contextPin get equalTo pinPage getPinObjFromUi 但我想打印到日志中以提供信息 这意味着我可以知道哪些字段不相等 所以我想到了实现一个匹配器 我用谷歌搜索过
  • 使用 Gson 反序列化 JSON 时引用父对象

    给定以下 JSON authors name Stephen King books title Carrie title The Shining title Christine title Pet Sematary 这个对象结构 publi
  • 您能解释一下流的概念吗?

    我知道流是字节序列的表示 每个流都提供了向其给定的后备存储读取和写入字节的方法 但流的意义何在 为什么我们与之交互的不是后备存储本身 不管出于什么原因 这个概念并不适合我 我读过很多文章 但我想我需要一个类比或其他东西 选择 流 这个词是因
  • java.lang.NoClassDefFoundError:无法解析:Landroid/webkit/PacProcessor

    实在找不到言语 我的项目只是一天天都无法编译 这就是我所做的 我下载并显示一个 PDF 然后将其作为保存的 PDF 打印到设备上 然后崩溃了 这是崩溃的情况 at java lang Class java lang Class classF
  • 将 UTC 日期转换为本地日期

    我正在将纪元时间 UTC 格式 转换为如下所示的格式 现在我尝试了不同的答案来转换UTCDate from UTC到当地时间 但我没有得到当地时间 任何帮助 将不胜感激 String epochTime 1436831775043 Date
  • 创建多彩板

    我要创建一个多彩板 从第一个方块开始为黑色 然后是蓝色 红色和黄色 这些方块对角线填充 并且没有空的彩色方块 我知道我的算法是错误的 但我不知道如何修复它 目前 我的代码打印如下 import javax swing JFrame impo
  • ListView Viewholder 复选框状态

    我的 ListView 自定义适配器 及其新实现的 viewHolder 有一些问题 我有一个 ListView 其中每个项目都有一个复选框 这里没有什么新内容 问题是 如果我的列表中有超过 9 个项目 当我选中第一个复选框时 第十个将被自
  • Android 中从时间戳获取日期名称

    我有一个类 当它初始化时 它会使用公共 getter 在私有字段中记录初始化时间 public class TestClass private long mTimestamp public TestClass mTimestamp Syst
  • 如何更改 ComboFieldEditor 的内容?

    我想更改其中一个的值ComboFieldEditor取决于另一个ComboFieldEditor在 Eclipse 插件中 例如 如果用户更改package 需要在第二个中填充不同的类ComboFieldEditor The ComboFi
  • 如何拆分 XML

    我的第一篇文章在这里 我已经搜索过 但没有找到我要找的东西 我不太确定需要什么技术来完成以下操作 我使用 Mule 3 3 CE 我需要拆分 XML 文件 我需要在每个分割的 XML 中保留 rootElement 及其属性 所有 XML
  • LocationManager requestLocationUpdates minTime OR minDistance

    我用的是安卓系统LocationManager及其方法requestLocationUpdates像这样 locationManager requestLocationUpdates LocationManager GPS PROVIDER
  • Jersey Rest 客户端未添加查询参数

    我正在尝试为 google 搜索 api 制作一个简单的球衣休息客户端 Client client ClientBuilder newClient WebTarget target client target https www googl

随机推荐

  • java final关键字修饰局部变量,final关键字的这8个小细节,你get到几个?

    今天来聊 final 关键字 因为最近在看的几本书都讲到了 final 关键字 发现好多小细节自己都忽视了 抽空总结了一下 分享给大家 正文 final关键字是一个常用的关键字 可以修饰变量 方法 类 用来表示它修饰的类 方法和变量不可改变
  • 数据在底层的存储模式

    1 数据的存储模式 大端存储模式 常见于我们的手机等 低地址放高数据 小端存储模式 比如PC 低地址存放低数据 面试题 设计程序判断大小端 这里可以有两种方式 1 写一个函数通过数据类型 int main int a 0x11223344
  • 我的服务器开发之路-安装mysql之mariadb并更改数据库路径

    centos最好安装mariadb 输入rpm qa grep mariadb 并没有显示版本号 则说明并没有安装mariadb 输入yum remove mysql mysql server mysql libs可完全卸载mysql相关
  • K8S个人学习之路

    服务器预备环境 1 永久禁用swap空间 1 临时关闭swap分区 重启失效 swapoff a 2 永久关闭swap分区 sed ri s swap etc fstab 2 修改k8s gcr io 路径的镜像 其他的镜像仓库 MY RE
  • Spark-RDD编程

    Spark在进行计算的时候通常会包含以下几个步骤 创建SparkContext上下文对象 使用SparkContext加载数据创建RDD RDD的转换算子transfotmations RDD的行动算子actions RDD的缓存和持久化
  • 反射获取字段的值与非空校验

    获取指定字段的值 通过字段对应的get方法 public Object getFieldValueByName1 String fieldName Object obj try String firstLetter fieldName su
  • 《Semi-Supervised Semantic Segmentation with Cross-Consistency Training》 2020CVPR 论文阅读

    在这项工作中 作者首先观察到 对于语义分割 低密度区域在隐藏表示中比在输入中更明显 作者提出了交叉一致性训练 其中预测的不变性是施加不同的扰动在编码器输出上 Cross Consistency Training 该模型包含一个共享的enco
  • SQL千万级大数据量查询优化

    转发自 https blog csdn net long690276759 article details 79571421 spm 1001 2014 3001 5506 防止查询资料找不到来源 很详细 1 对查询进行优化 应尽量避免全表
  • c++中istringstream及ostringstream超详细说明

    文章目录 1 stringbuf类介绍 1 1 stringbuf类构造函数 1 2 str函数 2 istringstream类 2 1 rdbuf函数 2 2 swap函数 3 ostringstream类和stringstream类
  • whisper

    Robust Speech Recognition via Large Scale Weak Supervision 介绍 大规模弱监督的训练 先前的方法都是通过大量的无监督学习训练 无监督的数据容易收集 所以通过大量无监督的学习可以训练出
  • Node中的事件循环

    Node中的事件循环 Node的底层语言是libuv 使用v8引擎解析js脚本 libuv负责调用接口API 将不同的任务交给不同的线程处理 再将处理结果交给v8引擎 v8引擎再将处理结果发送给用户 Node中任务的执行顺序 timers定
  • Mybatis-Plus:Service接口

    目录 IService接口 1 写实体类 2 写mapper接口 3 写service接口 4 写service接口的实现类 IService自带方法 1 save 2 SaveOrUpdate 3 Remove 4 Update 5 Ge
  • xss-domcobble绕过XSSfilter

    目录 DOM破坏的原理 例题 多层标签 HTMLCollection 一些常见的标签的关系 三层标签如何获取 例题 DOM破坏的原理 DOMClobber是一种攻击技术 它利用了DOM 文档对象模型 的特性来破坏或修改网页的结构和功能 DO
  • WDK李宏毅学习笔记第十五周01_Conditional Generation by Conditional

    Conditional Generation by GAN 文章目录 Conditional Generation by GAN 摘要 1 Supervised Conditional GAN 1 1 目的 1 2 做法 1 3 Discr
  • 把一个base64编码的图片绘制到canvas (canvas的图片在转成dataurl)

    把一个base64编码的图片绘制到canvas 需要引入jquery
  • SpringBoot中ThreadPoolTaskExecutor的使用

    文章目录 1 配置自己的线程池 2 使用 2 1 在Service层使用 2 2 多线程中使用事务的写法 2 3 方法内多线程 2 3 1 错误写法 2 3 2 正确写法 一 2 3 2 正确写法 二 2 3 3 正确写法 三 3 线程池与
  • mysql的相关技术说明_MySQL 系统架构 说明

    说明 本文转自 简朝阳 MySQL ACE 的 MySQL性能调优与架构设计 一 逻辑模块组成 总的来说 MySQL 可以看成是二层架构 第一层我们通常叫做SQL Layer 在MySQL 数据库系统处理底层数据之前的所有工作都是在这一层完
  • 计算机熔断与服务降级,Hystrix---服务熔断和服务降级

    一 服务熔断 防止服务雪崩 作用在服务提供者 服务熔断 熔断机制是应对雪崩效应的一种微服务链路保护机制 当扇出链路的某个微服务不可用或者响应时间太长时 会进行服务的降级 进而熔断该节点微服务的调用 快速返回 错误 的响应信息 当检测到该节点
  • Java多线程——Lock

    Lock 从JDK 5 0开始 Java提供了更强大的线程同步机制 通过显式定义同步锁对象来实现同步 同步锁使用Lock对象充当 java util concurrent locks Lock接口是控制多个线程对共享资源进行访问的工具 锁提
  • Java的静态绑定与动态绑定

    我们可以对思考一个问题 JVM是如何知道调用的是哪个类的方法源代码 这里面到底有什么内幕呢 这篇文章我们就将揭露JVM方法调用的静态 static binding 和动态绑定机制 auto binding 理解这两个绑定之前 我们不妨先理解