我们知道计算机是由晶体管、电路板等组装而成的电子设备,而这些电子设备其实只能识别0与1的信号。

  那么问题来了,我们在操作系统上编写的Java代码(由字母、数字等各种符号组成),打包后部署到服务器上,是如何被计算机所识别并运行的呢?另外,操作系统有很多种,包括Windows系统,Linux系统,Mac OS系统等,而我们同样的Java代码,却可以不做任何处理在不同的系统上正常运行,这又是为啥呢?

2、class 字节码文件介绍

 搞清楚了Java代码的跨平台原理,我们接着来介绍为什么编写的Java代码能够被计算机所识别。

  ①、字节码文件

  这其实是上面所说的语言无关性这个特性重要文件——class字节码文件的功劳。

  Java所有的指令大概有 200 个左右,一个字节(8位)可以存储 256 种不同的信息,我们将一个这样的字节称为字节码(ByteCode)。

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

3、无符号数和表

  在介绍这些十六进制之前,我们先介绍 Class 文件的数据类型。

  Class 文件采用一种类似于 C 语言结构体的伪结构来存储,这种伪结构只有两种数据类型:无符号数和表

①、无符号数

  这是一种基本数据类型,以 u1,u2,u4,u8 来分别代表 1个字节、2个字节、4个字节、8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或按照 UTF-8 编码构成的字符串值。

②、表

  表是由多个无符号数或其它表作为数据项所构成的复合数据类型,所有表都习惯行的以“_info”结尾。表用于描述有层次关系的复合结构数据。

  整个 Class 文件本质上就是一张表,结构如下:

java 模拟文件操作 java heap space java虚拟文件系统_版本号

  PS:需要说明的是,由于 Class 文件结构没有任何分隔符,所以无论是每个数据项的的顺序还是数量,都是严格限定的,哪个字节代表什么含义,长度多少,先后顺序如何,都是不允许改变的。

  下面,我们就来分别介绍这些数据项代表什么含义。

4、魔数

  每个 class 文件的头 4 个字节称为魔数(Magic Number),它的唯一作用是:标识该文件是一个Java类文件。如果没有识别到该标志,则说明该文件不是Java类文件或者文件已受损。

  由上图,我们可以看到前 4 个字节是 cafe babe。这是 Gosling 定义的一个魔法数,意思是 Coffee Baby。

  其实很多文件存储标准中都使用魔数进行身份识别,比如图片gif或者jpeg,使用魔数而不是使用扩展名来进行识别主要是基于安全考虑,因为文件扩展名可以任意的改动。

  5、Class 文件的版本号

  紧随魔数的 4 个字节存储的是 class 文件的版本号:第 5 和第 6 个字节是次版本号(Minor Version),第 7 和第 8 个字节是主版本号(Major Version)。

  Java的版本号是从 45 开始的,JDK1.1 之后的每个 JDK 大版本发布主版本号向上加1(JDK1.0~JDK1.1使用了45.0~45.3的版本号),高版本的 JDK 能向下兼容以前版本的 Class 文件,但不能运行以后版本的 Class 文件,即使文件格式未发生变化。

  上图第5、6、7、8个字节为 00 00 00 34。其十进制值为 52,是JDK8的内部版本号。

6、常量池

  待更新!!!