字节码文件组成
以正确的姿态打开文件
- 字节码文件中保存了源代码编译后的内容,以二进制的方式存储,无法直接用记事本打开。
- 可通过NotePad++使用十六进制插件查看class文件
- 推荐使用jclasslib工具查看字节码文件
jclasslib的Github地址:
Https://github.com/ingokegel/jclasslib
idea中直接下载插件jclasslib Bytecode Viewer
字节码文件中包括基础信息,常量池,字段,方法,属性五部分
字节码文件组成-基本信息
基本信息有魔数,主次版本号(jdk版本),常量池计数,接口数,字段数,方法数,访问标识,父类,接口等。
- Magic魔数
文件是无法通过文件扩展名来确定文件类型的,文件扩展名能随意更改,不影响内容。软件通过文件前几个字节(文件头)确定文件类型,如果不支持则报错。
class字节码文件前几个字节就叫做魔数,固定为0xCAFEBABE不会改变 - 主次版本号
主版本号用来标识大版本号(jdk版本)
大版本号(jdk)=主版本号-44
**版本号主要判断当前字节码与jdk版本是否兼容
字节码文件组成-常量池
- 字节码文件中常量池的作用:避免相同的内容重复定义,节省空间。
- 常量池中的数据都有一个编号,编号从1开始。在字段或者字节码指令中通过编号可以快速的找到对应的数据。
- 字节码指令中通过编号引用到常量池的过程称之为符号应用。
字节码文件组成-方法
字节码中的方法区域是存放字节码指令的核心位置,字节码指令存放在方法的Code属性中。
问:
int i=0;i=i++;
最终i的值是多少?
这个问题从字节码指令层面剖析
原理图:
字节码指令:
iconst_0//在图中操作数栈中临时存入0
istore_1//把操作数栈中的值存入局部变量表数组下标为1的位置(i的位置)至此完成int i=0;
iload_1//把i的值0放入操作数栈中,此时操作数栈中值为0
iinc 1 by 1//把局部变量表1号位置数值加1 完成i++操作。此时操作数栈中值为0,局部变量表i位置值为1
istore_1//把操作数栈中的值0放入局部变量表1位置(i位置)完成操作i=?。此时局部变量表i位置的值1被操作数栈的0替换。
return//结束,最终i=0
所以i最后的值为0捏,看完jvm虚拟机我恍然大悟,不知道有没有人和我一样写错的QAQ