Java字节码文件
Posted 狗哥狗弟齐头并进
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java字节码文件相关的知识,希望对你有一定的参考价值。
Java字节码文件
了解Java前端编译器
要让一个Java程序正确的运行在JVM,java文件必须通过前端编译器,将符合Java语言规范的代码转换成Java字节码文件。
只要能将Java原文件编译成正确的class文件,就可以在JVM上运行。
类文件结构
Clss文件包括下下几个部分:
- 魔数
- Class文件版本
- 常量池
- 访问标志
- 类索引,父类索引,接口索引
- 字段表集合
- 方法表集合
- 属性表集合
1 Class文件的标识
1.1 魔数(Magic Number)
- 每个Class文件开头的4个字节的无符号整数称为魔数。
- 它的唯一作用就是确定这个文件是否为一个能被虚拟机接受的有效合法的Class文件。魔数是Class文件的标识。
- 固定值为 0XCAFEBABE.不会改变。
- 如果一个Class文件开头没有魔数那么就会出现类格式异常错误。
- 使用魔数而不是扩展名来进行识别主要是基于安全方面的考虑,因为文件扩展名可以随意地改动。
1.2 Class文件版本号
- 紧接着魔数的4个字节存储的就是Class文件的版本号。同样是4个字节。第五个和第刘个字节所代表的含义就是编译的夫版本号,而第七个和第八个字节就是编译的主版本号。 先副后主。
- 它们共同构成了class文件的格式把本好。M.m。
- 版本号如下表所示。
版本号从45 开始,每一个大版本都增加1.
不同版本的Java编译器编译的Class文件对应的版本是不一样的。目前,高版本的Java虚拟机可以执行由低版本编译器生成的Class文件,但是低版本的Java虚拟机不能执行由高版本编译器生成的Class文件。否则JVM会抛出java.lang.UnsupportedClassVersionError异常
1.3 常量池
常量池是Class文件中内容最丰富的区域之一。常量池对于Class文件中的阻断和方法解析也有着至关重要的作用。
- 常量池是整个class文件的基石。
- 常量池表项中,用于存放编译期间生成的各种字面量和符号引用,这部分内容将在类加载后进入方法区的运行时常量池中存放。
1.3.1 常量池计数器
constant_pool_count
- 由于常量池 的数量不固定,时长时短,所以需要放置两个字节来标识常量池容量计数值。
- 常量池容量计数值(U2类型) 从1 开始 表示常量池中有多少项常量。=1表示有0个常量项。
1.3.2 常量池表
- constant_pool是一种表结构,以1-常量池计数器-1 为索引。表明了后面有多少个常量项。
- 常量池主要存放两大类常量: 字面量 和 符号引用。
- 它包含了class文件结构及其子结构中引用的所有字符串常量,类或接口名。常量池中的每一项都具有它的特征。第一个字节作为类型标记,用于确定该项的格式。这个字节称为标记字节。
1.4 访问标识
- 在常量池后,紧跟着就是访问标记。该标记使用两个字节标识。用于识别一些类或者接口曾琦的访问信息。如下图所示:
- 类的访问权限通常是 ACC_开头的常量
- 每一种类型的标识都是通过设置访问标记的32中的特定为来实现的。
1.5 类索引,父类索引,接口索引
- 会占两个字节来标识来指定该类的类别、父类类别以及实现的接口。
1.6 字段表集合
fields: 用于描述接口或类中声明的变量。字段包括累计变量以及实例级变量但是不包括方法内部、代码块内部声明的局部变量。
它指向常量池索引集合,描述了每个字段完整的信息。比如 字段的标识符,访问呢修饰符,是类变量还是实例变量,是否是的常量等,
1.6.1 字段表计数器
字段计数器标识当前class文件中字段表的成员格式。使用两个字节来表示。
字段表中的每一个车官员都是一个field_info结构,用于标识该类或接口所声明的所有类字段或者实例字段、不包括方法内部声明的变量,也不包括从父类或杜磊接口继承的那些字段。
1.6.2 字段表
- 字段表中的每个成员都必须是fields_info结构的数据项,用于标识当前类或接口中某个字段的完整描述。
- 字段表结构如下图:
1.7 方法表集合与属性表集合
以上是关于Java字节码文件的主要内容,如果未能解决你的问题,请参考以下文章