什么是字节码指令?[通俗易懂]

什么是字节码指令?[通俗易懂]字节码指令简介: Java虚拟机的指令由一个字节长度的、代表着某种特定含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成。由于Java虚拟机采用面向操作数栈而不是寄存器的架构,所以大多数的指令都不包含操作数,只有一个操作码。由于限制了Java虚拟机操作码的长度为一个字节,所以指令集的操作码总数不可能超过256条。字节码与数据…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

字节码指令简介: 
Java虚拟机的指令由一个字节长度的、代表着某种特定含义的数字(称为操作码,Opcode)以及跟随其后的零至多个代表此操作所需参数(称为操作数,Operands)而构成。 由于Java虚拟机采用面向操作数栈而不是寄存器的架构,所以大多数的指令都不包含操作数,只有一个操作码。由于限制了Java虚拟机操作码的长度为一个字节,所以指令集的操作码总数不可能超过256条。

字节码与数据类型:大部分与数据类型相关的字节码指令,他们的操作码助记符中都有特殊的字符来表明专门为哪种数据类型服务:i代表int,l代表long,s代表short等等。大部分指令都没有支持整型类型****byte、char和short以及boolean类型。编译器会在编译器或运行期将byte和short类型的数据带符号扩展为相应的int类型,将boolean和char类型数据零位扩展为相应的int类型数据。与之类似在操作boolean、byte、short和char类型的数组时,也会转换为只用对应的int类型的字节码指令来处理。因此大多数对于上述类型数据的操作,实际上都是使用相应的int类型作为运算类型。

加载和存储指令助记符: 
加载和存储指令用于将数据在栈帧中的局部变量表和操作数栈之间来回传输。 
load将一个局部变量加载到操作栈:iload、lload、fload等。 
store将一个数值从操作数栈存储到局部变量表:istore、lstore、fstore等。 
将一个常量加载到操作数栈:bipush、sipush、ldc等

运算指令助记符: 
加法指令:iadd、ladd、fadd、dadd 
减法指令:isub、lsub、fsub、dsub 
等等。

在Java虚拟机规范中定义了在除法指令(idiv和ldiv)以及求余指令(irem和lrem)中当出现除数为零时会导致虚拟机抛出ArithmeticException,其余整型运算场景都不应该抛出运行时异常。

类型转换指令: 
Java虚拟机直接支持以下数值类型的宽化类型转换: 
int类型到long、float或者double 
long类型到float、double 
float类型到double 
相对的,处理窄化类型转换时,必须显示的使用转换指令来完成,这些转换指令包括:i2b、i2c、l2i、f2i、d2i等等

对象创建与访问指令: 
创建类实例的指令:new 
创建数组的指令:newaray、anewarray 
访问类字段(static字段)和实例字段(非static字段)的指令:getfield、putfield、getstatic、putstatic 
把一个数组元素加载到操作数栈的指令:baload、caload、saload、iaload等等 
将操作数栈的值存储到数组元素中的指令:bastore、castore、sastore、iastore等等 
查数组长度的指令:arraylength 
检查实例类型的指令:instanceof、checkcast

操作数栈管理指令: 
将操作数栈顶一个或两个元素出栈:pop、pop2 
复制栈顶一个或两个数值将复制值或者双份的复制值重新压如栈顶:dup、dup2 
将栈最顶端的两个数值互换:swap

控制转移指令: 
控制转移指令可以让Java虚拟机有条件或无条件的从指定的位置执行而不是控制转移指令的下一条指令继续执行程序, 
可以认为控制转移指令就是在有条件或无条件的修改PC寄存器的值。 
条件分支:ifeq、ifnull等 
无条件分支:goto、goto_w、jsr、ret

方法调用和返回指令: 
invokevirtual指令:用于调用对象的实例方法。 
invokeinterface指令:用于调用接口方法,他会在运行时搜索一个实现了这个接口的对象,找出适合的方法进行调用。 
invokespecial指令:用于调用一些需要特殊处理的实例方法,包括实例初始化方法、私有方法和父类方法。 
invokestatic指令:用于调用类方法(static方法)。

异常处理指令: 
在Java程序中显示抛出异常的操作(throw)都有athrow指令来实现,除了用throw语句显示抛出异常情况之外,Java虚拟机规范还规定了许多运行时异常会在其他Java虚拟机指令检测到异常状况时自动抛出。例如,在整数运算中,当除数为零时,虚拟机会抛出ArithmeticException异常。在Java虚拟机中,处理异常(catch)不是由字节码来实现的,而是采用异常表(Code属性中)完成的。

同步指令: 
Java的同步分为方法级同步和方法内部一段指令序列同步(部分代码),这两种同步结构都是使用管程(Monitor)来支持的。 
方法级的同步:无需通过字节码指令来控制,他的实现在方法调用和方法返回中,虚拟机能通过Class结构表中通过方法表结构中的access_flags中的ACC_SYNCHRONIZED标志得知一个方法是否声明为同步方法。当方法调用时,调用指令将会检查方法的该标志位是否被设置了,如果为真,执行线程就要先成功持有管程,然后才能执行方法,最后当方法完成时(无论是正常完成还是非正常)释放管程。在方法执行期间,执行线程持有了管程,其他任何线程都无法再获得到管程,如果一个同步方法执行期间抛出了异常,并且在方法内部无法处理此异常,那么这个同步方法所持有的管程将在异常抛出到同步方法之外是自动释放。

指令集序列同步(部分代码同步):Java虚拟机使用monitorenter和monitorexit两条指令来支持synchronized关键字的语义。在执行代码前有monitorenter开始同步,在执行完代码退出以前有monitorexit退出同步。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/184758.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • lvs环境搭建

    lvs环境搭建参考:https://blog.csdn.net/Ki8Qzvka6Gz4n450m/article/details/79119665http://www.cnblogs.com/klb561/p/9215667.html补充了设置vip的方法以及一些解释性东西。 负载均衡集群是loadbalance集群的简写,翻译成中文就是负载均衡集群。常用的负载均衡开源软件有nginx、…

    2022年7月23日
    7
  • 图遍历算法的应用

    图遍历算法的应用1.判断图的连通性图的遍历算法可以用来判断图的连通性。如果一个无向图是联通的,如果无向图是联通的,则从任一节点出发,仅需一次遍历就可以访问图中的所有节点。如果无向图是非联通的,则从某一节点出发,一次遍历仅能访问到该顶点所在联通分量的所有顶点,而对于图中其他联通分量的顶点,则无法通过这次遍历访问。对于有向图来说,若从初始点到图中的每个顶点都有路径,则能够访问到图中的所有顶点,否则不能访问到所有顶…

    2022年5月4日
    50
  • eclipse SVN javaHL not available 问题解决「建议收藏」

    eclipse SVN javaHL not available 问题解决「建议收藏」SVN插件下载地址及更新地址,你根据需要选择需要的版本。Linksfor1.8.xRelease:EclipseupdatesiteURL:http://subclipse.tigris.org/update_1.8.xsvn插件包下载:http://subclipse.tigris.org/servlets/ProjectDocumentList?folderID=2240Linksfor1.6.xRelease:EclipseupdatesiteURL:ht…

    2022年10月14日
    2
  • python输出语句print用法_python print输出

    python输出语句print用法_python print输出【时间】2018.10.12【题目】python中的print输出函数用法总结 一、直接输出无论什么类型,数值,布尔,列表,字典…都可以直接输出,或者先赋值给变量,再输出。  二、格式化输出下面是《Python基础编程》中对格式化输出的总结:(1).%字符:标记转换说明符的开始(2).转换标志:-表示左对齐;+表示在转换值之前要加上正负号;“”(…

    2025年7月10日
    1
  • wireshark抓包新手使用教程_无root抓包使用教程

    wireshark抓包新手使用教程_无root抓包使用教程WireShark抓包使用教程–详细Wireshark是非常流行的网络封包分析软件,可以截取各种网络数据包,并显示数据包详细信息。常用于开发测试过程各种问题定位。本文主要内容包括:1、Wireshark软件下载和安装以及Wireshark主界面介绍。2、WireShark简单抓包示例。通过该例子学会怎么抓包以及如何简单查看分析数据包内容。3、Wireshark过滤器使用。通过过滤器可以筛选出想要分析的内容。包括按照协议过滤、端口和主机名过滤、数据包内容过滤。Wires…

    2025年9月29日
    4
  • 深拷贝和浅拷贝的区别,说法正确的是_前端浅拷贝和深拷贝的区别

    深拷贝和浅拷贝的区别,说法正确的是_前端浅拷贝和深拷贝的区别首先,明确一点深拷贝和浅拷贝是针对对象属性为对象的,因为基本数据类型在进行赋值操作时(也就是拷贝)是直接将值赋给了新的变量,也就是该变量是原变量的一个副本,这个时候你修改两者中的任何一个的值都不会影响另一个,而对于对象或者引用数据来说在进行浅拷贝时,只是将对象的引用复制了一份,也就内存地址,即两个不同的变量指向了同一个内存地址,那么在改变任一个变量的值都是该变这个内存地址的所存储的值,所以两个变量的值都会改变。一、clone()方法在Java中是用clone()方法实现深拷贝的,比如以下代码在Jav

    2022年10月1日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号