JVM学习-字节码指令集(二)
对象的创建与访问指令
创建指令
- 虽然类实例和数组都是对象,但Java虚拟机对类实例和数组的创建和操作使用了不同的字节码指令
- 创建类实例指令:new
- 它接收一个操作数,指向常量池的索引,表示要创建的类型,执行完成后,将对象的引用压入操作数栈
- 创建数组的指令
- 创建数组的指令:newarray,arewarray,multianewarray
- newarray:创建基本类型数组
- anewarray:创建引用类型数组
- multianewarray:创建多维数组
字段访问指令
- 对象创建后,可能通过对象访问指令获得对象实例或数组实例中的字段或数组元素
- 访问字段(static字段,或称为类变量)的指令:getstatic,putstatic
- 访问类实例字段(非static字段,可实例变量):getfield,putfield
如:以getstatic指令为例,它含有一个操作数,为指向常量池的Fieldref索引,它的作用是获取Fieldref指定的对象或者值,并将其压入操作数栈
public void sayHello() {System.out.println("hello");}
//对应字节码
0 getstatic #8 <java/lang/System.out>
3 ldc #9 <hello>
5 invokevirtual #10 <java/io/PrintStream.println>
8 return
数组操作指令
- 数组操作指令主要有:xastore和xaload指令
- 把一个数组元素加载到操作数栈的命令:baload,caload,saload,iaload,laload,faload,daload,aaload
- 将一个操作数栈的值存储到数组元素中的指令:bastore,castore,sastore,iastore,lastore,fastore,dastore,aastore
- 取数组长度的指令:arraylength
- 该指令弹出栈顶的数组元素,获取数组的长度,将长度压入栈
public void arrLength() {double[] arr = new double[10];System.out.println(arr.length);}//字节码0 bipush 102 newarray 7 (double)4 astore_15 getstatic #8 <java/lang/System.out>8 aload_19 arraylength //获取数组长度
10 invokevirtual #14 <java/io/PrintStream.println>
13 return
- 说明
- 指令xload表示将数组的元素压栈,如saload,caload表示压入short数组和char数组,指令xaload在执行时,要求操作数中栈顶元素为数组索引i,栈顶顺位第二个元素为数组引用a,该指令会弹出栈顶这两个元素,并将a[i]重新压入堆栈
- xastore则专门针对数组操作,以iastore为例,它用于给一个int数组的给定索引赋值,在iastore执行前,操作数栈顶需要以此准备3个元素:值、索引、数组引用,istore会弹出这三个值,并将值败给数组中指定索引的位置
public void setArray() {int[] intArray = new int[10];intArray[3] = 20;System.out.println(intArray[1]);}
//字节码0 bipush 102 newarray 10 (int)4 astore_1//----------------对应intArray[3] = 205 aload_1 //数组地址6 iconst_3 //索引7 bipush 20 //值9 iastore
//----------------对应intArray[3] = 20
10 getstatic #8 <java/lang/System.out>
//----------------对应intArray[1]
13 aload_1 //数组地址
14 iconst_1 //数组索引
15 iaload
//----------------对应intArray[1]
16 invokevirtual #14 <java/io/PrintStream.println>
19 return
类型检查指令
- 检查类实例或数组类型的指令:instanceof,checkcast
- 指令checkcast用于检查类型强制转换是否可以进行,如果可以进行,那么checkcast指令不会改变操作数栈,否则它会抛出CassCastException异常
- 指令instanceof用来判断是否是某一个类的实例,它会将判断结果压入操作数栈
public String checkCast(Object obj) {if (obj instanceof String) {return (String)obj;} else {return null;}}
//字节码指令0 aload_11 instanceof #17 <java/lang/String> //判断是否为String,即obj instanceof String4 ifeq 12 (+8)7 aload_18 checkcast #17 <java/lang/String> //强转
11 areturn
12 aconst_null
13 areturn
方法调用与返回指令
方法调用指令
- 方法调用指令:invokevirtual,invokeinterface,invokespecial,invokestatic,invokedynamic
- invokevirtual:用于调用对象的实例方法,根据对象的实际类型进行分派(虚方法分派),支持多态,是最常见的方法分派方式
- invokeinterface:用于调用接口方法,它会在运行时搜索由特定对象所实现的这个接口方法,并找出适合的方法进行调用
//方法调用指令:invokeinterfacepublic void invoke3() {Thread t1 = new Thread();((Runnable)t1).run();Comparable<Integer> com = null;com.compareTo(123);}//字节码0 new #4 <java/lang/Thread>3 dup4 invokespecial #5 <java/lang/Thread.<init>>7 astore_18 aload_19 invokeinterface #9 <java/lang/Runnable.run> count 1 //调用接口方法
14 aconst_null
15 astore_2
16 aload_2
17 bipush 123
19 invokestatic #10 <java/lang/Integer.valueOf>
22 invokeinterface #11 <java/lang/Comparable.compareTo> count 2
27 pop
28 return
- invokespecial:调用一些特殊处理的实例方法,包含实例初始化方法(构造器),私有方法和父类方法,这些方法是静态类型绑定的,不会在调用时动态派发
//方法调用指令:invokespecial:静态分派public void invoke1() {//情况1:类实例构造器方法Date date = new Date();Thread t1 = new Thread();//情况2:调用父类方法super.toString();//情况3:私有方法methodPrivate();}private void methodPrivate() {}
//字节码指令0 new #2 <java/util/Date>3 dup4 invokespecial #3 <java/util/Date.<init>>7 astore_18 new #4 <java/lang/Thread>
11 dup
12 invokespecial #5 <java/lang/Thread.<init>> //构造器调用
15 astore_2
16 aload_0
17 invokespecial #6 <java/lang/Object.toString> //父类方法调用
20 pop
21 aload_0
22 invokespecial #7 <com/chapter10/MethodInvokeReturnTest.methodPrivate> //私有方法调用
25 return
- invokestatic:调用命名类中的类方法(static方法),这是静态绑定的
//调用指令:invokestaticpublic void invoke2() {methodStatic();}public static void methodStatic() {}
//字节码
0 invokestatic #8 <com/chapter10/MethodInvokeReturnTest.methodStatic>
3 return
- invokedynamic:调用动态绑定的方法,JDK1.7新加入的指令,用于在运行时动态解析出调用点限定符所引用的方法,并执行该方法,前4条调用指令的分派逻辑都固化在java虚拟机内部,而invokedynamic指令的分派逻辑是由用户所设定的引导方法决定的
方法返回指令
- 方法调用结束前,需要进行返回,方法返回指令是根据返回值的类型区分的
- 包括ireturn(boolan,byte,char,short和int类型使用),lreturn,freturn,dreturn和areturn
- 还有一条return指令供声明为void的方法,实例初始化方法以及类和接口的类初始化方法使用
- 举例
- 通过ireturn指令,将当前函数操作数栈的顶层元素弹出,并将这个元素压入调用者函数的操作数栈中,所有在当前函数操作数栈中的其他元素都会被丢弃
- 如果当返回值是synchronized方法,那么还会执行一个隐含的monitorexit指令,退出临界区
- 最后,会丢弃当前方法的整个帧,恢复调用者的帧,并将控制权转交给调用者
//方法返回指令public int returnInt() {int i = 200;return i;}
//字节码
0 sipush 200
3 istore_1
4 iload_1
5 ireturnpublic double returnDouble() {return 0.0;}//字节码0 dconst_0
1 dreturnpublic String returnString() {return "hello,world";}
//字节码
0 ldc #16 <hello,world>
2 areturnpublic int[] returnArr() {return null;}//字节码public float returnFloat() {int i = 10;return i;}
//字节码
0 bipush 10
2 istore_1
3 iload_1
4 i2f
5 freturnpublic byte returnByte() {return 0;}
//字节码
0 iconst_0
1 ireturn
相关文章:

JVM学习-字节码指令集(二)
对象的创建与访问指令 创建指令 虽然类实例和数组都是对象,但Java虚拟机对类实例和数组的创建和操作使用了不同的字节码指令创建类实例指令:new 它接收一个操作数,指向常量池的索引,表示要创建的类型,执行完成后&am…...

解密网络流量监控:优化IT运维的利器
引言: 在当今数字化时代,网络流量监控是维护网络稳定与业务连续性的关键。作为一名资深网络工程师,我将分享一些关于网络流量监控的重要知识,并探讨如何在IT运维中运用这一工具优化网络性能,确保业务的顺畅进行。 1. 网…...
oracle 分区表常用语句(2)
给分区表增加分区 第一种不存在MAXVALUE(直接添加即可) ALTER TABLE T6 ADD PARTITION P5 VALUES LESS THAN(TO_DATE( 2018-08-01 00:00:00, SYYYY-MM-DD HH24:MI:SS, NLS_CALENDARGREGORIAN));第二种存在MAXVALUE alter table T6 split PARTITION P4 at(TO_DAT…...
Python函数式编程进阶:用函数实现设计模式
文章目录 函数式编程进阶:用函数实现设计模式案例实现:构建“策略”模式使用函数实现”策略“模式享元 选择最佳策略:简单的方式 globals关键字 函数式编程进阶:用函数实现设计模式 案例实现:构建“策略”模式 策略模…...

Ingress controller:Kubernetes 的瑞士军刀
原文作者:Brian Ehlert of F5 原文链接:Ingress controller:Kubernetes 的瑞士军刀 转载来源:NGINX 中文官网 NGINX 唯一中文官方社区 ,尽在 nginx.org.cn 许多人认为 Ingress controller(Ingress 控制器&…...
uniapp tabBar app页面滚动闪屏的问题
我在做app的时候,调试tabBar页面滚动时莫名其妙的闪屏,其他页面不闪屏,可能跟新建的项目样式有关。 修改方法如下。 在pages.json中 "tabBar": {"selectedColor": "#204AFF","color": "#ccc…...

【计算机毕业设计】388微信小程序足球赛事及队伍管理系统
🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板ÿ…...
监控易监测对象及指标之:华为FusionInsight Kafka服务全方位监控
监控易提供对华为FusionInsight Kafka服务的全方位监控功能。该功能可以帮助用户实时监测Kafka服务的各项性能指标,确保服务的稳定运行和高效性能。 具体功能点包括: 服务状态监测:监控易能够实时监测华为FusionInsight Kafka服务的运行状态…...

Python装饰器的应用
Python 中的装饰器是一种语法糖,可以在运行时,动态的给函数或类添加功能。装饰器本质上是一个函数,使用 函数名就是可实现绑定给函数的第二个功能 。它的作用就是在不修改被装饰对象源代码和调用方式的前提下为被装饰对象添加额外的功能。 …...
【数据结构与算法 | 基础篇】力扣232, 225
1. 力扣232 : 用栈实现队列 (1). 题 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty): 实现 MyQueue 类: void push(int x) 将元素 x 推到队列的末尾int pop() 从队列的开头移…...

内网(极空间)搭建gitlab跳板机转发端口及域名配置
背景说明 https://blog.csdn.net/GodDavide/article/details/139182475 上文说到: 我已经用docker搭好了gitlab-ce服务,但我是部署在自己的家庭nas-极空间z4pro里的,属于内网环境。 另外我有一台阿里云服务器,做跳板机。 我有一个阿里的域名…...
如何知道自己电脑的 Shell类型是什么?
在macOS中,你可以通过以下几种方法来确定当前正在使用的shell类型,并了解相关的配置文件: 1. 使用终端命令确定shell类型 打开终端应用程序(Terminal)。输入以下命令并按回车键:echo $SHELL。该命令会输出…...

Axios的使用简单说明
axios 请求方式和参数 axios 可以发送 ajax 请求,不同的方法可以发送不同的请求: axios.get:发送get请求 axios.post:发送post请求 axios.put:发送put请求 axios.delete:发送delete请求 无论哪种方法,第一…...
查找list集合中,持续时间>=ContinueTime的数据集合,保存在新的list中
在给定的包含时间戳的list中,查找连续continueNum次的且时间间隔为needDiff的集合。 eg:相邻两个数据的时间戳间隔为1分钟,且超过30分钟有数据 /**** param list 包含时间戳(10位)的list* param continueNum 至少持续…...
nginx 反向代理配置详解
Nginx 反向代理是一种常用的部署策略,用于将客户端请求转发到内部网络中的一个或多个服务器,这些服务器直接处理请求并返回响应给Nginx,再由Nginx转交给客户端。这种设置可以提高网站的可用性和安全性,同时也能实现负载均衡、缓存…...

微信小程序毕业设计-农场驿站平台系统项目开发实战(附源码+论文)
大家好!我是程序猿老A,感谢您阅读本文,欢迎一键三连哦。 💞当前专栏:微信小程序毕业设计 精彩专栏推荐👇🏻👇🏻👇🏻 🎀 Python毕业设计…...
CAN总线应用协议CANopen
作为一种真正开放的CAN总线高层协议,CANopen协议允许不同的CAN设备以标准化的方式进行通讯,这使得CAN 设备具有互操作性。随着CANopen协议的日益完善,它已经广泛应用于多个行业。本文将对CANopen协议的对象字典、通讯对象、网络管理等几个方面…...
htop安装不了怎么解决
🌟🌌 欢迎来到知识与创意的殿堂 — 远见阁小民的世界!🚀 🌟🧭 在这里,我们一起探索技术的奥秘,一起在知识的海洋中遨游。 🌟🧭 在这里,每个错误都…...

vue 笔记02
目录 01 事件修饰符 02 按键修饰符 03 v-bind属性 04 vue-axios的基本使用 05 vue的生命周期 06 vue生命周期涉及到的其他的知识点 01 事件修饰符 vue的事件修饰符 事件名称.修饰符1.修饰符2...事件驱动函数 stop 阻止冒泡修饰符 prevent 阻止默认行为 once 当前事件只触…...
MySQL8.0免安装及phpmyadmin配置
安装包解压,运行mysqld文件后,启动net start,提示成功,但进入phpmyadmin登录页面后,输入用户名,提示不支持空密码,config.default.php设置密码后,提示 mysqli::real_connect(): (HY…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者
抖音增长新引擎:品融电商,一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中,品牌如何破浪前行?自建团队成本高、效果难控;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...

AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
作为测试我们应该关注redis哪些方面
1、功能测试 数据结构操作:验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化:测试aof和aof持久化机制,确保数据在开启后正确恢复。 事务:检查事务的原子性和回滚机制。 发布订阅:确保消息正确传递。 2、性…...

Sklearn 机器学习 缺失值处理 获取填充失值的统计值
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 使用 Scikit-learn 处理缺失值并提取填充统计信息的完整指南 在机器学习项目中,数据清…...