搜索
写经验 领红包

一个class文件到底包含了哪些东西(一个class文件可以有两个类吗)

导语:一个class文件到底包含了哪些东西

通过对一个class文件的分析,基本理解了class文件结构,在这里最后再做一个总结,梳理下class文件内容。

两种结构

class文件内容如果泛化的区分可以分成两种结构:

1、字节数据:通过预先指定结构的占用字节数来存储基本的数据类型,比如class文件最开始的几个字节按顺序存储了魔数、小版本、大版本,再比如字段结构的访问标识符,都是通过提前确定了结构所占用的字节数,根据占用的字节来存储数据;

2、表:表是由字节数据和其他的表结构组合而成,比如整个class文件就可以当成一个表结构,它是由常量池数据这种基本结构和常量池、方法结构等表结构组成;

表结构还有一种特殊结构,可以看成一个数组结构,比如常量池结构就是一种由多种常量池类型组成的数组结构,比如方法结构也是一个数组结构,一个类中有多个方法,方法结构就是多个方法组成的结构;

每一个数组结构的出现必定会出现数组长度,它属于字节数据,用来表述接下来出现的数组结构的长度;

再看class结构

class原结构如下图:

用两种结构来展示表达class结构如下图:

用这种方式来表达class文件结构感觉更加清晰,class中包含的信息如下魔数、小版本、大版本、常量池、访问标注、当前类、父类、接口、字段、方法、属性。这样一看一个class文件仅仅表达这些信息,其中常量池、接口、字段、方法数组结构。

再看常量池

常量池也是一个常量池数组,主要由以下表结构组成:

常量池表结构也分为两种结构,存储字符串的基础结构、由多个指向基础结构常量池数组索引的组合结构,所有常量池表第一个字节tag是用来确定结构类型,根据表类型来判断接下来字节是存储还是指向。

常量池相当于class文件的资源库,存储了后面字段、接口、方法等需要的字符串,后面结构使用只需要指向常量池索引。

字段、方法、属性

方法与字段结构如下图:

字段与方法的结构完全相似,他们最主要的区别在于attributes,方法的属性包含Code、LineNumberTable、LocalVariableTable等属性结构,用来表达方法的执行过程、对应源码行号、本地变量等比字段需要更多的属性来表达。

attribute种类巨多,并且还会持续的扩展,就不能仅仅像常量池那样通过固定字节来区分到底是那种attribute,而是通过attribute_name_index指向常量池中存储的具体名称,再通过attribute_length来确定attribute所占的位数。attribute是class文件中最灵活多变的结构,同时它的使用也存在class、方法、字段等结构中。

总结

字节数据就像是基础数据,而表结构则是组合结构,而class文件通过这两种结构实现层层递进,完整的存储了需要表达的内容,使得JVM拿到class文件能够通过确定的结构进行层层解释,这样既精简了class文件内容也使JVM能快速、准确的加载class文件。

通过学习class字节码,能够学习到一些平时很难了解到的知识,比如一个类支持的最大字段、方法数量,一个方法最长有多长等。不过学习到最重要的是JVM对数据的处理方式,class是如何通过最少的内容表达出完整的信息的方式!

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!

本文内容由快快网络小樊创作整理编辑!