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 需要四行指令