Class类文件结构概述

简介: 参考文献:周志明《深入理解Java虚拟机》第二版关于Class文件class 文件应该是所有 Java 程序员都必定知道的文件,因为我们的 Java 源代码经过 javac 编译以后就会得到这个 class 文件。

参考文献:周志明《深入理解Java虚拟机》第二版

关于Class文件

class 文件应该是所有 Java 程序员都必定知道的文件,因为我们的 Java 源代码经过 javac 编译以后就会得到这个 class 文件。但是,它虽然与 Java 关系密切可它并不仅仅属于 Java,因为它属于虚拟机,虚拟机能够执行的就是 class 文件。所以我们 Java 虚拟机,其实就根本不认识 Java。
不过,也正是因为 JVM 只认识这个 class 文件,才使得 Java 有了最NB的一大特色:“一次编译,到处运行”。JVM 无论在哪,只需要带着这个 class 文件就能跑代码。但是,其实这种平台无关性也并不是最NB的地方,因为 JVM 的设计者们想要实现的最终目标是 语言无关性 ,就是让其他的语言也能跑在 JVM 上,真正的实现“大一统”,比如现在一些语言就推出了 JVM 版本,例:Jython(Python), JRuby(Ruby), Rhino(JavaScript),Groovy 等。所以 Java 程序员们,不要担心 Java 会被替代,好好学 JVM ,以后一定前途无量啊!

好了,言归正传


Class文件结构概述

因为 class 文件结构这里比较繁琐,而且大部分是固定的数据结构,所以我只简单的整理一下,详细的信息请从参考资料查阅

class 文件是一组以 8 位字节为基础单位的二进制流,各个数据项目按照顺序紧凑地排列在 class 文件中,中间没有添加任何分隔符,这使得整个 class 文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要占用 8位字节以上空间的数据项时,则会按照高位在前的方式分割成若干个 8 位字节进行存储

class 文件只有两种数据类型:无符号数,表
无符号数是基本类型,以 u1, u2, u4, u8 分别代表 1 个字节,2 个字节,4 个字节, 8 个字节的无符号数
表是由多个无符号数或其他表作为数据项构成的复合数据类型,所有表都以“_info”结尾,甚至可以说整个 class 文件就是一张表
这里写图片描述
这张表就是 class 文件中包含的所有数据项
我们接下来逐一进行介绍

魔数(magic number)与版本(version)

从表中可以看出,class 文件的第一个数据项是一个 u4 类型,占 4 个字节的 魔数,它的唯一作用是用来确定该 class 文件是否可以被虚拟机接受,这个作用就相当于文件的后缀名,.txt,.jpg,.gif,.mp4等等,那为什么不用后缀名呢?因为这样隐式的更加安全,class 文件的 magic number 很有意思,它的值为:0xCAFFBABE (咖啡宝贝),这个名字在 Java 还叫 Oak 的时候就确定了缘由是开发人员喜欢喝咖啡,这也是 Java 的 logo 的由来

接着后面是 2 个字节的次版本号(minor version)2 个字节的主版本号(major version)


常量池(constant_pool)

再下来是就是 class 文件的资源仓库 常量池 了,它是 class 文件结构中与其他项目关联最多的数据类型,也是占用空间最大的数据项之一
因为常量池的大小不固定,它由程序决定,所以在它之前是一个 u2 的常量池容量计数值(constant_pool_count)后面的数据项都是一样,所有 _info 类型的数据项大小都是由程序决定,所以前面都有一个计数值
这里需要注意的是,constant_pool_count 是从 1 开始计数的,空出 0 是为了表示“不引用任何一个常量池项目”

常量池中主要存放两大类常量:字面量符号引用
字面量:文本字符串,final常量等
符号引用:类和接口全限定名,字段的名称和描述,方法的名称和描述

常量池中每一项常量都是一个表,目前有这 14 种
这里写图片描述
这其中每一个类型的表都还有自己的结构
例:
这里写图片描述
这里写图片描述
所以这也是常量池占存大的原因


访问标志(access_flags)

常量池结束后,就是 u2 的访问标志它用来识别一些类或接口层次的访问信息
例:判断是 class 还是 interface,标记修饰符 public, protected, abstract等
这里写图片描述

类索引(this_class),父索引(super_class),接口索引集合(interfaces)

类索引为 u2,父索引为 u2,接口索引集合为一个 u2 集合(前面还有一个 u2 的计数器 interface_count)
根据 Java 语言的规则,除了 java.lang.Object 之外,其他所有类的父类均不为 0
这里写图片描述
这里写图片描述


字段表集合(fields)

字段表用来描述接口或者类中声明的变量字段包括类级变量和实例级变量,但不包括在方法内部声明的局部变量。
这里写图片描述
access_flags 就是用来标记字段作用域,修饰符等信息
这里写图片描述
注意,从表中我们可以看出,这些字段标记是严格按照 Java 规则制定的,例:
private int m 的 access_flags 就为:0002
public static int m 的 access_flags 就为:0001(public)+ 0008(static)= 0009
protected final double m 的 access_flags 就为:0004(protected)+ 0010(final)= 0014
然后是 name_index 和 descriptor_index ,分别代表字段的简单名称和字段和方法的描述符
描述符规则:基本类型用字母表示,数组用“[”表示,方法参数用“()”括起来
这里写图片描述
例:
void inc() 描述符为:“()V”
java.lang.String.toString() 描述符为:“()Ljava/lang/String;”
int indexOf(char[]source,int sourceOffset,int sourceCount,char[]target,int targetOffset,int targetCount,int fromIndex) 描述符为:“([CII[CIII)I”

字段表集合中不会列出从超类或者父类接口中继承的字段,但可能列出原本 Java 代码中不存在的字段,如,在内部类中添加指向外部类实例的字段(保持外部访问性)
对 Java 来说,无论描述符如何,字段都不能重名
对字节码来讲,如果字段描述符不同,重名也是合法的


方法表集合(methods)

这部分的结构与字段表几乎相同
这里写图片描述

这里针对字段与方法的不同,在访问标志上有修改

这里写图片描述

仔细查看方法表结构,你会发现,方法中的代码并不在其中,因为,方法里的 Java 代码,经过编译器编译成字节码指令后,存放在方法属性表集合(attributes)中一个名为“Code”的属性里


属性表集合(attributes)

class 文件对于这一数据项的要求比较宽松,它不必有严格的顺序,并且只要不与已有的属性名重复,任何人实现的编译器都可以向属性表写入自己定义的属性信息(支持用户自主扩展)
在最新的《Java虚拟机规范(Java SE 7)》中有 21 项预定义的属性,
例:
这里写图片描述
完整表格请查阅参考资料

所有预定义或是自定义的属性都应该符合属性表结构
这里写图片描述
这其中的每一个属性都有自己的结构表,里面包含了其所定义的一些数据

目录
相关文章
|
6月前
|
存储 Java 程序员
【 class文件结构】
【 class文件结构】
|
11月前
|
存储 Java 开发者
【Class文件结构】
【Class文件结构】
|
Java 索引
Class文件结构分析
Class文件结构分析 1. Class文件的结构概览图 2. 每一项数据说明 类型 名称 数量 说明 u4 magic 1 魔数:确定一个文件是否是Class文件 u2 minor_version
74 0
|
存储 NoSQL Java
class文件结构详解
写在最前:学习class文件结构不像学习JVM内存结构、垃圾收集器那样,可以对我们写代码时有很多帮助,学习了JVM内存结构,我们在配置虚拟机参数时就会有更全面的考虑,写代码时就可以注意到代码的的优化空间,学习了垃圾收集器,让我们可以根据服务器的配置,更好的选择出适合程序最大吞吐量的收集器,更好的根据服务器硬件配置出合适的参数,学习class呢,则更多的是为了让我们知其然,也知其所以然,让我们知道我们写出的代码在JVM里面到底是怎么运行的,这部分内容会相对枯燥,白话多一些,这里主要分两个部分来详细讲述class文件的机构[class文件结构、字节码指令]。
100 0
class文件结构详解
|
存储 XML Java
JVM虚拟机-Class文件简介
JVM虚拟机-Class文件简介
109 0
JVM虚拟机-Class文件简介
|
存储 XML Oracle
【JVM深度解析】Class文件结构
你了解Class文件结构吗?那你知道为什么会有魔数吗?定义的类变量会在什么地方出现呢?...不懂?一文带你了解Class文件结构。
【JVM深度解析】Class文件结构
|
Java Scala Kotlin
深入学习和认识class文件内部结构
深入学习和认识class文件内部结构
107 0
|
前端开发 JavaScript
前端培训-中级阶段(31)- Class的基本语法,Class的继承(2019-12-26期)
前端最基础的就是 HTML+CSS+Javascript。掌握了这三门技术就算入门,但也仅仅是入门,现在前端开发的定义已经远远不止这些。前端小课堂(HTML/CSS/JS),本着提升技术水平,打牢基础知识的中心思想,我们开课啦(每周四)。
134 0
前端培训-中级阶段(31)- Class的基本语法,Class的继承(2019-12-26期)
|
存储 Java C++
JVM的class文件结构详解(二)
JVM的class文件结构详解(二)
87 0
JVM的class文件结构详解(二)