java字节码

  我们都知道Java字节码是JVM所使用的指令集。java字节码可以分为如下几类:

操作数栈

  Java 方法的栈桢分为操作数栈和局部变量区。通常来说,程序需要将变量从局部变量区加载至操作数栈中,进行一番运算之后再存储回局部变量区中。操作数栈的指令有如下:

  • dup 复制栈顶元素(常用于复制 new 指令所生成的未经初始化的引用。)如下代码生所的字节码:

dup

  • pop 指令常用于舍弃调用指令的返回结果。当调用了有返回值的方法却不用返回值时需要有个pop指定,如下图所示:

pop

  • iconst,lconst, fconst, dconst, aconst, bipush, sipush,可以将不同类型的常量加载到操作数栈中。这几个指令的操作范围与类型如下表:

指令

类型

范围

iconst

int(boolean, byte, char, short)

[-1, 5]

lconst

long

0, 1

fconst

float

0, 1,2

dconst

double

0, 1

dconst

reference

null

bipush

int(boolean, byte, char, short)

[-128,127]

sipush

int(boolean, byte, char, short)

[-32768,32767]

代码与指令的对应关系如下图所示:

指令对应图

  • ldc 加载常量池中的常量值。

Idc加载常量池中的例子

  • 将局部变量区的值加载到操作数栈的指令   Java 虚拟机将局部变量区当成一个数组,依次存放 this 指针(仅非静态方法),所传入的参数,以及字节码中的局部变量。存储在局部变量区的值,通常需要加载至操作数栈中,方能进行计算,得到计算结果后再存储至局部变量数组中。这些加载、存储指令如下表所示:

类型

加载指令

存储指令

int(boolean, byte, char, short)

iload

istore

long

lload

lstore

float

fload

fstore

double

dload

dstore

reference

aload

astore

局部变量表的字节码

  • iinc M, N指令,(其中 M为正整数,N为整数),用于操作局部变量区。表求的含义为:将局部变量数组的第 M 个单元中的 int 值增加 N,常用于 for 循环中自增量的更新。字节码如下图所示:

iinc例子

Java 相关指令
  • new: 后跟目标类,生成该类的未初始化的对象。
  • instanceof:后跟目标类,判断栈顶元素是否为目标类 / 接口的实例。是则压入 1,否则压入 0。如图所示:

instanceof

  • checkcast:后跟目标类,判断栈顶元素是否为目标类 / 接口的实例。如果不是便抛出异常
  • athrow:将栈顶异常抛出
  • monitorenter/monitorexit 为栈顶对象加解锁。如下图所示:

monitorenter、monitorexit

  • getstatic、putstatic用于访问静态字段。
  • getfield、putfield用于访问实例子段。

getfield、getstatic

数组相关指令
  • newarray:新建基本类型数组。
  • anewarray:新建引用类型数组
  • multianewarray :生成多维数组
  • arraylength: 求数组的长度。 数组相关的加载与存储指令如下表:

类型

加载指令

存储指令

byte(boolean)

baload

bastore

char

caload

castore

short

saload

sastore

int

iaload

iastore

long

laload

lastore

float

faload

fastore

double

daload

dastore

reference

aaload

aastore

image.png

返回值相关指令

根据不同的返回类型,有不同的指令。如下表所示:

返回类型

返回指令

void

return

int(boolean, byte, char, short)

ireturn

long

lreturn

float

freturn

double

dreturn

reference

areturn

其它
  • goto:无条件跳转指令
  • tableswitch 和 lookupswtich:tableswitch针对密集的 cases,lookupswtich针对稀疏的 cases。

goto、switch指令

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我是业余自学C/C++的

redis_3.0.7_sds.c_sdsIncrLen()

12620
来自专栏Java学习网

Java面试中最常见的10个问题,Java底层知识,花点时间学习一下

1.什么是 Java 虚拟机?为什么 Java 被称作是“平台无关的编程语言”? Java 虚拟机是一个可以执行 Java 字节码的虚拟机进程。Java 源文...

28950
来自专栏用户2442861的专栏

C++ STL空间配置源码分析以及实现二

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/haluoluo211/article/d...

10520
来自专栏深度学习之tensorflow实战篇

利用python内置函数,快速统计单词在文本中出现的次数

#coding=utf-8 import collections import os with open('str.txt') as file1:#打开文本...

42980
来自专栏大闲人柴毛毛

Redis源码分析(四)——Redis数据结构-整数集合

1. 整数集合特点 有序:集合中所有值按照从小到大顺序排列。 不重复 可以存储int16_t、int32_t、int64_t三种类型的整数 1. 数据结构 t...

39870
来自专栏史上最简单的Spring Cloud教程

Java 代理模式

什么是代理 代理是一种设计模式,它的核心思想,是将对目标的访问转移到代理对象上。这样做的好处就是,目标对象在不改变代码的情况下,可以通过代理对象加一些额外的功能...

22480
来自专栏Python小屋

《Python程序设计》判断题1-240题

1、Python是一种跨平台、开源、免费的高级动态编程语言。(对) 2、Python 3.x完全兼容Python 2.x。(错) 3、Python 3.x和Py...

5K80
来自专栏GreenLeaves

JavaScript之面向对象学习五(JS原生引用类型Array、Object、String等等)的原型对象介绍

1、原型模式的重要性不仅仅体现在创建自定义类型方面,就连所有的原生的引用类型(Obejct、Array、String等等)都在构造函数的原型上定义方法和属性。如...

217100
来自专栏九彩拼盘的叨叨叨

JS模式 之通用模式(译)

原文 http://shichuan.github.io/javascript-patterns/

11230
来自专栏领域驱动设计DDD实战进阶

04-TypeScript中的方法新功能(上)

在TypeScript中,提供了一些函数的新功能,能够简化JavaScript中的一些比较复杂代码才能实现的一些能力。 在C#后端语言中,能够对方法传递的参数指...

28540

扫码关注云+社区

领取腾讯云代金券