深入理解JVM虚拟机第二十五篇:详解JVM方法的绑定机制静态绑定和动态绑定,早期绑定晚期绑定,并编写代码从字节码角度证明这件事情

news2025/1/23 3:47:08

大神链接:作者有幸结识技术大神孙哥为好友,获益匪浅。现在把孙哥视频分享给大家。

孙哥链接:孙哥个人主页
作者简介:一个颜值99分,只比孙哥差一点的程序员
本专栏简介:话不多说,让我们一起干翻JVM

本文章简介:话不多说,让我们讲清楚JVM当中与操作数栈相关的动态链接和常量池的作用

文章目录

一:方法的调用

1:概述

2:静态链接

3:动态链接

二:方法的绑定

1:绑定概念

2:早期绑定

3:晚期绑定

三:晚期绑定示例

1:编写代码

2:jclasslib查看内容

四:早期绑定示例 

1:编写代码

2:jclasslib查看内容

五:总结说明


一:方法的调用

        我们每天都在写方法的调用,但是我们能搞明白其中的原理和JVM当中的操作步骤么?这就是本文的意义。

1:概述

        官方说法:

        在JVM中,将符号引用转换为调用方法的直接引用这个操作是跟JVM当中方法的绑定机制息息相关的。

        说人话:

        上边这段话是什么意思?我这里给大家解释一下,我们javap整理完毕字节码文件之后,我们会可以在任意一个方法中查看code下的字节码指令,很多字节码指令的后边都会跟#数字这么一个概念,这个就是符号引用,这个引用指向常量池。

        所谓将符号引用转换为方法的直接引用,就是将这个字节码指令后边的符号引用,转变为真实的方法。

        下列中的#3就是符号引用。

  public void methodB();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=3, locals=1, args_size=1
         0: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
         3: ldc           #6                  // String methodB().....
         5: invokevirtual #5                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
         8: aload_0
         9: invokevirtual #7                  // Method methodA:()V
        12: aload_0
        13: dup
        14: getfield      #2                  // Field num:I
        17: iconst_1
        18: iadd
        19: putfield      #2                  // Field num:I
        22: return

        从上述找一个例子的话,就是将偏移地址为9的字节码指令后边的#7这个符号引用用真实的方法字面量代替

2:静态链接

        官方说法:

        当一个字节码文件被装载进JVM内部时,如果被调用的目标方法在编译期可知且运行期保持不变时。这种情况下将调用方法的符号引用转换为直接引用的过程称之为静态链接。

        说人话:

        静态链接:这种方式在编译阶段就已经把符号引用直接转换为了直接引用。

3:动态链接

        官方说法:

        如果被调用的方法在编译期无法被确定下来,也就是说,只能够在程序运行期将调用方法的符号引用转换为直接引用,由于这种引用转换过程具备动态性,因此也就被称之为动态链接。

        说人话:

        动态链接:这种方式在运行阶段才能把符号引用直接转换为直接引用。

二:方法的绑定

1:绑定概念

        绑定是一个字段、方法或者类在符号引用被替换为直接引用的过程,这仅仅发生一次。这个不论是编译器确定还是运行期确定都只会发生一次,不会修改。

        对应的方法的绑定机制为:早期绑定 (Early Bindng)和晚期绑定(Late Binding)。

2:早期绑定

        官方说法:

        早期绑定就是指被调用的目标方法如果在编译期可知,且运行期保持不变时即可将这个方法与所属的类型进行绑定,这样一来,由于明确了被调用的目标方法究竟是哪一个,因此也就可以使用静态链接的方式将符号引用转换为直接引用。

        说人话:

        早期绑定是和我们的静态绑定相对应的。

3:晚期绑定

        官方说法:

        如果被调用的方法在编译期无法被确定下来,只能够在程序运行期根据实际的类型绑定相关的方法,这种绑定方式也就被称之为晚期绑定

        说人话:

        晚期绑定是和我们的动态绑定相对应的。

三:晚期绑定示例

1:编写代码

class Animal {
    public void eat(){
        System.out.println("动物进食");
    }
}

interface Huntable{
    void hunt();
}

class Dog extends Animal implements Huntable{
    @Override
    public void eat(){
        System.out.println("狗吃骨头");
    }

    @Override
    public void hunt() {
        System.out.println("捕食耗子,多管闲事");
    }
}

class Cat extends Animal implements Huntable{
    @Override
    public void eat(){
        System.out.println("猫吃鱼");
    }

    @Override
    public void hunt() {
        System.out.println("捕食耗子,天经地义");
    }
}

public class AnimalTest{
    public void showAnimal(Animal animal){
        animal.eat();//晚期绑定
    }

    public void showHunt(Huntable h){
        h.hunt();//晚期绑定
    }

}

2:jclasslib查看内容

四:早期绑定示例 

1:编写代码

class Animal {
    public void eat(){
        System.out.println("动物进食");
    }
}

interface Huntable{
    void hunt();
}

class Dog extends Animal implements Huntable{
    @Override
    public void eat(){
        super.eat();//早期绑定
        System.out.println("狗吃骨头");
    }

    @Override
    public void hunt() {
        System.out.println("捕食耗子,多管闲事");
    }
}

class Cat extends Animal implements Huntable{
    public Cat(){
        super();//早期绑定
    }
    public Cat(String name){
        this();//早期绑定
    }
    
    @Override
    public void eat(){
        System.out.println("猫吃鱼");
    }

    @Override
    public void hunt() {
        System.out.println("捕食耗子,天经地义");
    }
}

public class AnimalTest{
    public void showAnimal(Animal animal){
        animal.eat();//晚期绑定
    }

    public void showHunt(Huntable h){
        h.hunt();//晚期绑定
    }

}

2:jclasslib查看内容

        光标放到cat这个类上查看他的jclasslib

         invokeSpecial是早期绑定字节码指令,invokevirtual是晚期绑定的字节码指令。

五:总结说明

        随着高级语言的横空出世,类似于Java一样的基于面向对象的编程语言如今越来越多,尽管这类编程语言在语法风格上存在一定的差别,但是它们彼此之间始终保持着一个共性,那就是都支持封装、继承和多态等面向对象特性

        既然这一类的编程语言具备多态特性,那么自然也就具备早期绑定和晚期绑定两种绑定方式。

        Java中任何一个普通的方法其实都具备虚函数的特征,也就是运行期才能确定下来,它们相当于c++语言中的虚函数 (c++中则需要使用关键字virtual来显式定义)。

        如果在Java程序中不希望某个方法拥有虚函数的特征时,则可以使用关键字final来标记这个方法。也就是一个方法不想被晚期绑定,直接把他给final修饰即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1210003.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑屏幕标记软件——Pointofix

前言 Pointofix是一款由德国人开发的屏幕标记软件,德国人的工匠精神,是出了名的,德国人开发的软件也一样。 Pointofix体积非常小巧,安装包只有1MB大小,使用Pointofix可以直接在屏幕上面写字、画图、标重点。 下面介…

基于单片机的电源切换控制器设计(论文+源码)

1.系统设计 在基于单片机的电源切换控制器设计中,系统功能设计如下: (1)实现电源的电压检测; (2)如果电压太高,通过蜂鸣器进行报警提示,继电器进行切换,使…

【Java 进阶篇】JQuery DOM操作:CRUD操作的前端魔法

在前端开发的舞台上,CRUD(Create, Read, Update, Delete)操作是一种极为重要的技能,它涉及对页面元素的增删改查。而JQuery,这位前端开发的魔法师,为我们提供了便捷而强大的方法,使得CRUD操作变…

Winform / WPF 自定义控件 —— IPV4 地址输入框

在开始阅读本文之前,如果您有学习创建自定义控件库并在其他项目中引用的需求,请参考:在Visual Studio中创建自定义Winform控件库并在其他解决方案中引用https://blog.csdn.net/YMGogre/article/details/126508042 0、引言 Winform / WPF 框架…

视频推拉流EasyDSS直播点播平台获取指定时间快照的实现方法

视频推拉流直播点播系统EasyDSS平台,可提供流畅的视频直播、点播、视频推拉流、转码、管理、分发、录像、检索、时移回看等功能,可兼容多操作系统,在直播点播领域具有广泛的场景应用。为了便于用户集成、调用与二次开发。 今天我们来介绍下在…

Telnet 测试 UDP 端口?

Telnet 并不支持 UDP 端口的测试,可以使用 nc 命令来进行测试。nc 命令两种都支持: TCP # nc -z -v -u [hostname/IP address] [port number] # nc -z -v 192.168.10.12 22 Connection to 192.118.20.95 22 port [tcp/ssh] succeeded! UDP # nc -z -v…

算法通关村第十六关青铜挑战——原来滑动窗口如此简单!

大家好,我是怒码少年小码。 从本篇开始,我们就要开始算法的新篇章了——四大思想:滑动窗口、贪心、回溯、动态规划。现在,向我们迎面走来的是——滑动窗口思想!😝 滑动窗口思想 概念 在数组双指针里&am…

Python机器学习、深度学习提升气象、海洋、水文领域实践应用

Python是功能强大、免费、开源,实现面向对象的编程语言,能够在不同操作系统和平台使用,简洁的语法和解释性语言使其成为理想的脚本语言。除了标准库,还有丰富的第三方库,Python在数据处理、科学计算、数学建模、数据挖…

Live800:金牌客服常用的6大提问技巧

在客服行业,提问技巧是非常重要的一项技能。好的提问技巧不仅能够帮助客服人员更好地了解客户需求,还能够提高客户满意度和忠诚度。以下是金牌客服常用的6大提问技巧,希望能够对客服人员提升工作效率有所帮助。 1、开放性问题 开放性问题是指…

实现线程的多种方式锁的介绍ThreadLocal线程池 详细总结(上)

1、介绍 1. 线程回顾 2. 各种所的认识 3. JUC 并发库 4. ThreadLocal 5. 线程池 2、线程回顾 进程: 进程是资源( CPU 、内存等)分配的基本单位,它是程序执行时的一个实例。程序运行时系 统就会创建一个进程,并为…

图论17-有向图的强联通分量-Kosaraju算法

文章目录 1 概念2 Kosaraju算法2.1 在图类中设计反图2.2 强连通分量的判断和普通联通分量的区别2.3 代码实现 1 概念 2 Kosaraju算法 对原图的反图进行DFS的后序遍历。 2.1 在图类中设计反图 // 重写图的构造函数public Graph(TreeSet<Integer>[] adj, boolean dire…

JVM虚拟机:垃圾回收器之G1

本文重点 在前面的课程中我们介绍了六个垃圾回收器,分别是新生代的三个以及老年代的三个,本文我们将介绍一个垃圾回收器,它既可以用于新生代又可以用于老年代,这个垃圾回收器就是G1。 G1垃圾回收器的特点 G1是一种服务器端的并发收集垃圾回收器,应用在多处理器和大容量…

Zookeeper 命令使用和数据说明

文章目录 一、概述二、命令使用2.1 登录 ZooKeeper2.2 ls 命令&#xff0c;查看目录树&#xff08;节点&#xff09;2.3 create 命令&#xff0c;创建节点2.4 delete 命令&#xff0c;删除节点2.5 set 命令&#xff0c;设置节点数据2.6 get 命令&#xff0c;获取节点数据 三、数…

PBHA(page based hardware attributes)的介绍

基本介绍 基于页面的硬件属性 (PBHA&#xff1a;page based hardware attributes) 是一项可选的、由实现定义的功能。 它允许软件在转换表中设置最多四位&#xff0c;然后通过事务通过内存系统传播这些位&#xff0c;并可在系统中用于控制系统组件。这些位的含义特定于系统设计…

论文浅尝 | 用于开放式文本生成的事实增强语言模型

笔记整理&#xff1a;李煜&#xff0c;东南大学硕士&#xff0c;研究方向为知识图谱 链接&#xff1a;https://proceedings.neurips.cc/paper_files/paper/2022/hash/df438caa36714f69277daa92d608dd63-Abstract-Conference.html 1. 动机 生成式语言模型&#xff08;例如 GPT-3…

本田发布全新CB1000 Hornet,是杜卡迪街霸劈了腿还是Z1000红杏出墙?

米兰车展上&#xff0c;本田带来了全新的大黄蜂CB1000 Hornet&#xff0c;外观方面抛弃了之前的本田推出的Neo Sports Caf风格&#xff0c;新款的外观看起来要更加战斗一点。不过新的这个前脸改的&#xff0c;我只能说是杜卡迪街霸劈了腿还是Z1000红杏出墙&#xff1f;外观方面…

【LLM】0x00 大模型简介

0x00 大模型简介 个人问题学习笔记大模型简介LLM 的能力&#xff1a;LLM 的特点&#xff1a; LangChain 简介LangChain 核心组件 小结参考资料 个人问题 1、大模型是什么&#xff1f; 2、ChatGPT 在大模型里是什么&#xff1f; 3、大模型怎么用&#xff1f; 带着问题去学习&a…

石原子科技亮相2023成都市信息领域新产品发布会

2023年11月13日至15日&#xff0c;由成都市互联网信息办公室、四川天府新区管委会、成都市经信局市新经济委、成都市农业农村局指导的以“信息创造价值 创新引领未来”为主题的成都市信息领域新产品发布会在科创生态岛1号馆举行。围绕人工智能、区块链、数字化绿色化、数字乡村…

c题目8:打印斐波那契数列前100项

每日小语 终日寻春不见春&#xff0c;芒鞋踏破领投云。 归来偶把梅花嗅&#xff0c;春在枝头已十分。——无尽藏 解析题目 1.斐波那契数列是什么&#xff1f; 斐波那契数列是一个数列&#xff0c;其中每个数字等于前两个数字的和。数列的前几个数字是0、1、1、2、3、5、8、…

软件外包开发的开发文档

软件开发文档是一个重要的工具&#xff0c;用于记录和传达项目信息&#xff0c;帮助开发团队和利益相关者理解项目的各个方面。以下是一般性的软件开发文档编写格式&#xff0c;不同组织和项目可能有所不同&#xff0c;但这些通用准则可以帮助确保文档的清晰性和易读性&#xf…