作者:它山之石
时间:2021年12月15日

简介

java在诞生初期就有一个非常响亮的口号:一次编译,到处运行。这足够表明了java团队强大的野心,事实也证明了java从诞生到现在的用户数量和每年的编程类语言排行榜中都是名列前茅,那么它是怎么的实现平台无关性呢?我们都知道java虚拟机统一识别的文件存储结构是字节码,虚拟机帮助我们屏蔽掉了各个系统之间的差异,最后只要是代码通过编译后生成字节码文件就可以在虚拟机上运行,通过这个字节码文件我们就可以实现一次编译,到处运行,这就是文件今天要说的类文件。

类文件的结构

类文件是一组以8个字节为基础单位的二进制流,在这个二进制流中个数据项严格紧密的按顺序排列在一起,中间没有任何的分隔符,这些数据都是程序运行时所必需的,如果当所需存储超过8个字节则以高位在前为基础分割成若干个8字节来进行存储。
java中的类文件结构采用的是类似于C语言的伪结构来存储数据,这种伪结构里只存在两种数据类型:无符号数和表。

  1. 无符号数是基本的数据类型,通常以u1、u2、u4、u8 来表示 1字节、2字节、4字节、8字节的无符号数,无符号数可以用来表示数字、索引引用、数量值、UTF-8编码构成的字符串。
  2. 表是一种复合型数据结构,由多个无符号数或者其他表构成,所有的表名都以_info结尾,class文件也可以看成是一个表。

当我们要表示多个无符号数或者表的时候,通常会以一个前置数量计数值加若干个连续的数据项来表示某一类型的数据的集合。
这些数据项的顺序、数量、哪个字节代表什么意思、长度等都受到了严格的限制并且不能改变。

魔数与类文件版本号

  1. 类文件中开头的前4个字节就是魔数,作用是确定一个文件是否是一个正确的类文件,也就是说是否能被虚拟机认可,值是 0xCAFEBABE。
  2. 第5和第6个字节是类文件的次版本号,第7和第8个字节是类文件的主版本号,java的版本号是从45开始。

    常量池

    紧接着主次版本号之后的就是常量池入口,常量池也是class文件的资源库,也是占用空间最大的数据项之一,还是出现的第一个表结构数据项。

  3. 因为常量池的容量是不确定的,所以入口处第一项数据是U2类型的常量池容量计数值 ,计数值是从1开始计算,接口索引集合、字段表结合、方法表集合的容量计数值都是从0开始。

  4. 常量池里的两大常量是字面量和符号引用