Java虚拟机 -方法调用

news2025/5/23 7:46:20

方法调用

  • 方法调用
    • 静态链接
    • 动态链接
    • 案例
    • 虚方法与非虚方法
      • 虚方法(Virtual Method)
      • 非虚方法(Non-Virtual Method)
    • 方法返回地址

方法调用

我们编写Java程序的时候,我们自己写的类通常不仅仅是调用自己本类的方法。调用别的类的方法的时候,从字节码的角度,我们调用别的类的方法,字节码里面存储的是别的类的符号引用。
在这里插入图片描述
但是JVM运行的时候,我们需要一个机制去把这个符号,转化成实际的引用的类方法的地址,这样我们运行的时候,才能够找到要调用的方法。
在JVM中,将符号引用转化为调用方法的直接引用与方法的绑定机制有关,方法的绑定机制有两种:

  1. 静态绑定
  2. 动态绑定

静态链接

Java源代码转化成字节码文件装载到JVM区域的时候,如果被调用的类的目标方法,编译期间就可以确定下来的话,而且运行期间不会变。这时候,我们可以将调用方法的符号引用直接转化成目标方法的直接引用,这种情况就是静态链接或者早期绑定。

动态链接

被调用的方法如果编译期间无法确定下来,这种情况,程序只能够在运行期间将调用方法的符号引用转化成直接引用,这种情况就叫动态链接或者晚期绑定。

案例

class Student{

    public void study() {
        System.out.println("begin study");
    }
}

interface Play{
    public void play();
}

class JuniorStudent extends Student implements Play{
    @Override
    public void play() {
        System.out.println("JuniorStudent play");
    }
}

class MiddleStudent extends Student implements Play{

    @Override
    public void play() {
        System.out.println("MiddleStudent play");
    }
}


public class LinkTest {

    public void play(Play play) {
        play.play();
    }

    public void study(Student student) {
        student.study();
    }
}

虚方法与非虚方法

JVM的实现机制

  1. 虚方法调用
    JVM使用虚方法表(vtable)实现动态分派。每个类维护一个虚方法表,记录方法的实际入口地址。调用时根据对象的实际类型查表,找到正确的方法实现。
  2. 非虚方法调用
    直接通过符号引用在编译期确定调用目标,无需运行时查找。

虚方法(Virtual Method)

虚方法是支持动态绑定(运行时绑定)的方法,具体调用的方法实现由对象的实际类型(运行时类型)决定。Java中,默认情况下,未被final、private或static修饰的实例方法都是虚方法。

特点

  • 动态绑定:方法调用在运行时根据对象的实际类型确定。

  • 支持多态:允许子类重写(Override)父类方法,实现多态。

  • 虚方法表(vtable):JVM通过虚方法表快速查找方法的实际实现。

class Animal {
    public void speak() { // 虚方法(可被重写)
        System.out.println("Animal speaks");
    }
}

class Dog extends Animal {
    @Override
    public void speak() { // 重写父类方法
        System.out.println("Dog barks");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.speak(); // 输出 "Dog barks"(动态绑定到Dog的speak方法)
    }
}

常见虚方法

  • 普通实例方法(未被final、private、static修饰)。

  • 接口的默认方法(default方法)。

  • 抽象方法(abstract方法)。

非虚方法(Non-Virtual Method)

非虚方法是静态绑定(编译时绑定)的方法,调用的具体方法在编译期就能确定,与对象的实际类型无关。这些方法无法被重写,或不需要动态分派。

特点

  • 静态绑定:方法调用在编译时确定。

  • 无法被重写:子类无法修改其行为。

  • 性能更高:无需运行时查找方法表。

class Parent {
    public static void staticMethod() { // 非虚方法(静态方法)
        System.out.println("Parent's static method");
    }

    private void privateMethod() { // 非虚方法(private方法)
        System.out.println("Parent's private method");
    }

    public final void finalMethod() { // 非虚方法(final方法)
        System.out.println("Parent's final method");
    }
}

class Child extends Parent {
    // 尝试重写静态方法(实际是隐藏,而非重写)
    public static void staticMethod() {
        System.out.println("Child's static method");
    }

    // 无法重写private方法和final方法
}

public class Test {
    public static void main(String[] args) {
        Parent parent = new Child();
        parent.staticMethod(); // 输出 "Parent's static method"(静态绑定)
    }
}

常见的非虚方法

  • 静态方法(static):属于类,调用时基于引用类型。

  • 私有方法(private):仅在类内部可见,无法被重写。

  • final方法:禁止子类重写。

  • 构造方法:隐式调用,无法被动态分派。

  • 通过super调用的父类方法:直接指定父类实现。

方法返回地址

当一个方法开始执行之后,只有两种可能:

  1. 正常结束,当前方法栈帧出栈, 返回上一个方法的栈帧;
  2. 异常结束,如果本方法没有处理异常的方法,方法就会异常退出,不会给调用者提供任何返回值

无论是怎样退出,在方法退出之后,都需要恢复到被调用之前的那个方法的栈帧的当时的状态,程序才能正常往下执行。从栈的角度,方法退出,实际上是当前栈帧出栈,要恢复上层方法的局部变量表与操作数栈,如果有返回值,还需要把返回值压入操作数栈,然后将程序计数器指向上层方法的下一条指令的地址。

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

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

相关文章

JMeter JDBC请求Query Type实测(金仓数据库版)

文章目的 在实际性能测试中,JMeter的JDBC Request组件常用于模拟数据库操作。但许多用户对Query Type参数的具体行为存在疑惑。 本文将以金仓数据库KingbaseES为例,通过实测验证每种Query Type的行为,帮助用户明确其使用场景和限制&#xff…

【内部教程】ISOLAR-AB配置以太网栈|超详细实战版

目录 往期推荐 缩写与定义 关于系统描述(System Description) 1.1 EthCommunicationController 1.2 EthCommunicationConnector 1.2.1 Ports(端口) 1.3 EthPhysicalChannel(以太网物理通道) 1.3.1…

Nginx 核心功能

目录 一:正向代理 1:编译安装 Nginx (1)安装支持软件 (2)创建运行用户、组和日志目录 (3)编译安装 Nginx (4)添加 Nginx 系统服务 2:配置正…

【Canvas与图标】圆角方块蓝星CSS图标

【成图】 120*120的png图标 大小图&#xff1a; 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>圆角方块蓝星CSS Draft1</…

机器学习 day05

文章目录 前言一、模型选择与调优1.交叉验证2.超参数搜索 前言 通过今天的学习&#xff0c;我掌握了机器学习中模型的选择与调优&#xff0c;包括交叉验证&#xff0c;超参数搜索的概念与基本用法。 一、模型选择与调优 模型的选择与调优有许多方法&#xff0c;这里主要介绍较…

C#新建打开文件对话框

这是Winform直接封装好的打开文件对话框 using System.Windows.Forms; public static string OpenFile(string path) {OpenFileDialog openFileDialog new OpenFileDialog();// 设置对话框属性openFileDialog.Title "选择文件";openFileDialog.InitialDirectory …

汇川PLC通过开疆智能Profinet转ModbusTCP网关读取西门子PLC数据案例

本案例是客户通过开疆智能Profient转ModbusTCP网关连接汇川PLC的配置案例 Modbus TCP主站即Modbus TCP客户端&#xff0c;Modbus TCP主站最多支持同时与31个Modbus TCP从站 。&#xff08;Modbus TCP服务器&#xff09;进行通信。 第一步设置PLC IP地址&#xff1b; 默认PLC…

零基础入门:MinerU 和 PyTorch、CUDA的关系

&#x1f4a1;一句话总结&#xff1a;MinerU 是一个用 PyTorch 跑模型的程序&#xff0c;PyTorch 支持多种加速方式&#xff08;如 CUDA、MPS&#xff09;&#xff0c;让它跑得快就需要依赖这些加速工具。 PyTorch官网安装教程&#xff08;可根据系统情况选择不同版本&#xf…

借助IEDA ,Git版本管理工具快速入门

01 引言 一直使用SVN作为版本管理工具&#xff0c;直到公司新来的一批同事&#xff0c;看到我们使用的SVN都纷纷吐槽&#xff0c;什么年代了&#xff0c;还使用SVN。聊下来&#xff0c;才知道人家公司早早就将SVN切成了Git工具&#xff0c;并吐槽SVN的各种弊端。 既然新的技术…

三维空间,毫秒即达:RTMP|RTSP播放器在Unity中的落地实现

有人问我&#xff1a;在 Unity 里做超低延迟的直播播放&#xff0c;是什么感觉&#xff1f; 我说&#xff0c;是把一帧帧流动的时间&#xff0c;嵌进一个三维的空间里。 它不属于现在&#xff0c;也不属于过去。 它属于“实时”——属于那一秒内刚刚发生&#xff0c;却已被你看…

ubuntu 搭建FTP服务,接收部标机历史音视频上报服务器

1.安装vsftpd 1.1.安装命令 sudo apt update sudo apt install vsftpd 1.2.备份原始配置文件 sudo cp /etc/vsftpd.conf /etc/vsftpd.conf.bak 1.3.配置 vsftpd 编辑配置文件 /etc/vsftpd.conf&#xff1a; sudo vim /etc/vsftpd.conf 将以下参数修改为对应值&#xff…

一、内存调优

一、内存调优 什么是内存泄漏 监控Java内存的常用工具 内存泄露的常见场景 内存泄露的解决方案 内存泄露与内存溢出的区别 内存泄露&#xff1a;在Java中如果不再使用一个对象&#xff0c;但是该对象依然在GC ROOT的引用链上&#xff0c;这个对象就不会被垃圾回收器回收&…

Java的Filter与Spring的Interceptor的比较

一、技术规范与框架依赖 维度FilterInterceptor所属规范Servlet 规范&#xff08;Java EE 标准组件&#xff09;Spring MVC 框架组件&#xff08;非 Java EE 标准&#xff09;框架依赖不依赖 Spring&#xff0c;仅需 Servlet 容器&#xff08;如 Tomcat&#xff09;依赖 Sprin…

WPF···

设置启动页 默认最后一个窗口关闭,程序退出,可以设置 修改窗体的icon图标 修改项目exe图标 双击项目名会看到代码 其他 在A窗体点击按钮打开B窗体,在B窗体设置WindowStartupLocation=“CenterOwner” 在A窗体的代码设置 B.Owner = this; B.Show(); B窗体生成在A窗体中间…

微服务架构中的多进程通信--内存池、共享内存、socket

目录 1 引言 2 整体架构简介 3 疑问 3.1 我们的共享内存消息机制是用的posix还是system V 3.2 rmmt中&#xff0c;不同线程之间的比如访问同一个内存&#xff0c;用的什么锁控制的 3.3 疑问&#xff1a;假如一个进程发送给了另外两个进程&#xff0c;然后另外两个进程都同…

电脑中所有word文件图标变白怎么恢复

电脑中的word文件图标变白&#xff0c;如下图所示&#xff1a; 解决方法&#xff1a; 1.winR-->在弹出的运行窗口中输入“regedit”(如下图所示)&#xff0c;点击确定&#xff1a; 2.按照路径“计算机\HKEY_CLASSES_ROOT\Word.Document.12\DefaultIcon”去找到“&#xff0…

RK3568 OH5.1 源码编译及问题

安装编译器和二进制工具 在源码根目录下执行prebuilts脚本&#xff0c;安装编译器及二进制工具。 bash build/prebuilts_download.sh在源码根目录执行如下指令安装hb编译工具&#xff1a; python3 -m pip install --user build/hb使用build.sh脚本编译源码 进入源码根目录&…

Qt5、C++11 获取wifi列表与wifi连接

一、获取wifi列表 .h 文件内容 #include <QWidget> #include <QVBoxLayout> #include <QPushButton> #include <QCheckBox> #include <QListWidget>class Setting : public QWidget {Q_OBJECT public:explicit Setting(QWidget *parent nul…

【KWDB 2025 创作者计划】_从部署开始了解KWDB

一、概述 KaiwuDB 是一款面向 AIoT 场景的分布式、多模融合、支持原生 AI 的数据库产品&#xff0c;支持同一实例同时建立时序库和关系库并融合处理多模数据&#xff0c;具备时序数据高效处理能力&#xff0c;具有稳定安全、高可用、易运维等特点。面向工业物联网、数字能源、…

高等数学-微分

一、一元函数&#xff1a; 在实际应用中&#xff0c;经常需要近似计算函数yf(x)的增量Δyf(x)-f(x0)f(x0Δx)-f(x0),其中一种近似称为函数的微分。 定义&#xff1a;若函数yf(x)在点x0处的增量Δy可表达为自变量增量Δx的线性函数AΔx和Δx的高阶无穷小量之和&#xff0c;即Δ…