一文讲清楚JVM字节码文件的组成

01-以正确的姿势打开文件

字节码文件中保存了 源代码编译之后的内容,以 二进制的方式 存储,无法直接用记事本打开阅读

通过NotePad++使用十六进制插件查看class文件:

推荐使用 jclasslib 工具查看字节码文件;
Github地址: https://github.com/ingokegel/jclasslib

02-字节码文件的组成

字节码文件总共可以分为以下几个部分:

  • 基础信息 :魔数、字节码文件对应的 Java版本号、访问标识(public final 等)、父类和接口信息
  • 常量池: 保存了 字符串常量、类或接口名、字段名,主要在字节码指令中使用
  • 字段: 当前类或接口声明的 字段信息
  • 方法: 当前类或接口声明的方法信息,核心内容为方法的字节码指令
  • 属性: 类的属性,比如源码的文件名、内部类的列表等

2.1 基本信息

基本信息包含了jclasslib中能看到的两块内容:一般信息 和 接口

01-魔数

02-主副版本号

03-其它基础信息

2.2 常量池

字节码文件中常量池的作用:避免相同的内容重复定义,节省空间

本质是一个数组

2.3 方法

通过分析方法的字节码指令,可以清楚地了解一个方法到底是如何执行的。先来看如下案例:

java 复制代码
int i = 0;
int j = i + 1;

这段代码编译成字节码指令之后是如下内容:

关于三条字节码指令的说明:

  • iconst_常量值:将 该常量放入操作数栈 中;
  • istore_数组下标:将 操作数栈中的值 放到 局部变量表对应的数组下标 中;
  • iload_数组下标:将 局部变量表中对应数组下标的值取出来放到操作数栈 中

01-操作数栈 & 局部变量表

要理解这段字节码指令是如何执行的,我们需要先理解两块内存区域:操作数栈和局部变量表。

  • 操作数栈 是用来存放临时数据的内容,是一个栈式的结构,先进后出;
  • 局部变量表 是存放方法中的局部变量,包含方法的参数、方法中定义的局部变量,在编译期就已经可以确定方法有多少个局部变量

02- i = i++ 的执行流程

i++ 的字节码指令如下:

  • 其中 iinc 1 by 1 指令指的是 将局部变量表1号位置增加1,其实就实现了i++的操作

最终结果仍为 0

03- i = ++i 的执行流程

而 ++i 只是对两个字节码指令的顺序进行了更改:iioad_1 和 iinc 1 by 1

最终结果为 1

04-经典面试题

05-思考

i++:iinc 1 by 1;
k+=1:iinc 2 by 1

i++ 和 k+=1 都是一行 iinc _ by 1 就搞定了,但是 j = j + 1 需要四行指令

相关推荐
摇滚侠3 分钟前
DBeaver 导入数据库 导入 SQL 文件 MySQL 备份恢复
java·数据库·mysql
keep one's resolveY26 分钟前
SpringBoot实现重试机制的四种方案
java·spring boot·后端
天空属于哈夫克31 小时前
企业微信API常见的错误和解决方案
java·数据库·企业微信
摇滚侠2 小时前
VMvare 虚拟机 Oracle19c 安装步骤,远程连接 Oracle19c,百度网盘安装包
java·oracle
梁萌2 小时前
idea报错找不到XX包的解决方法
java·intellij-idea·启动报错·缺少包
Agent产品评测局2 小时前
生产排期与MES/ERP系统打通,实操方法详解 —— 2026企业级智能体自动化选型与实战指南
java·运维·人工智能·ai·chatgpt·自动化
阿丰资源2 小时前
基于Spring Boot的电影城管理系统(直接运行)
java·spring boot·后端
呱牛do it2 小时前
企业级门户网站设计与实现:基于SpringBoot + Vue3的全栈解决方案(Day 8)
java
消失的旧时光-19433 小时前
Spring Boot 工程化进阶:统一返回 + 全局异常 + AOP 通用工具包
java·spring boot·后端·aop·自定义注解
NE_STOP3 小时前
Redis--发布订阅命令和Redis事务
java