本文是《深入理解Java虚拟机》第二版 中类文件结构一章的读书笔记。
6.1概述
原来由于计算机只认识0和1,所以我们写的程序需要经过编译翻译成0和1构成的二进制格式才能由计算机执行.10多年时间过去了,计算机还是只认识0和1,但由于最近10年内虚拟机及大量建立在虚拟机之上的程序语言如雨后春笋般出现并蓬勃发展,将我们编写的程序编译成二级制本地机器码已不再是唯一的选择,越来越多的程序语言选择了与操作系统和机器指令集无关的,平台中立的格式作为程序编译后的存储格式
6.2 无关的基石
在 Java 发展之初,设计者就曾经考虑过并实现了让其他语言运行在 Java 虚拟机之上的可能性,他们在发布规范文档的时候,也刻意把 Java 的规范拆分成了 Java 语言规范及 Java 虚拟机规范。
时至今日,商业机构和开源机构已经在java语言之外发展处一大批在java虚拟机之上的允许的语言,如Clojure,Groovy,Jruby,Jython,Scala等,java虚拟机不和包括java在内的任何语言绑定,它只与"class文件"这种特定的二进制文件格式所关联,例如,使用java编译器可以把java代码编译为存储字节码的class文件,使用JRuby等其他语言的编译器一样可以把程序代码编译成class文件,虚拟机不关心class的来源是何种语言,如图1-1所示
Class文件是一组以8bit为基础单位的二进制流,各个数据项目严格按顺序紧凑地排列在class文件中,中间无任何添割符。Class文件格式采用一种类似于C语言结构体的伪结构来储存数据,这种伪结构只有两种数据:无符号数和表。
无符号数属于基本的数据类型,以u1,u2,u3,u4,u8表示1个字节,2个字节,3个字节,4个字节,8个字节,无符号数可以用来描述数字,索引引用,数量值或者按照UTF-8编码构成字符串。
表是由多个无符号数或者其它表作为数据项构成的复合数据类型,所有表都习惯地以"_info"结尾。表用于描述由层次关系的复合结构的数据,整个class文件本质上就是一张表。
图1-2
无论是无符号数还是表,当需要描述同一类型但数量不定的多个数据时,经常会使用一个前置的容量计数器加若干个连续的数据项的形式,这时称这一系列连续的某一类型的数据为某一类型的集合 .
接下来根据案列讲解一些概念:
新建一个简单的Hello.java类,代码如下:
public class Hello {
public static void main(String[] args) {
int a = 1;
int b = 2;
int c = a + b;
System.out.println(c);
}
}
利用javac命令编译Hello.java,生成Hello.class文件,再用 sublime text3打开Hello.class文件,如图1-3所示
图1-3
其中两位16进制数表示一个字节
每个Class文件的头4个字节称为魔数,它的唯一作用是确定这个文件是否为一个能被虚拟机接受的Class文件。很多文件储存标准中都使用魔数来进行身份识别,譬如图片格式,如 gif 或者 jpeg 等在文件头中都存有魔数。
使用魔数而不是扩展名来仅从识别主要是基于安全方面的考虑,因为文件扩展名可以随意地改动。文件格式的制定者额可以自由地选择魔数值,只要这个魔数值还没有被广泛采用过同时又不会引起混淆即可。
Class 文件的魔数的获得很有“浪漫气息”,值为:0xCAFEBABE(咖啡宝贝?),这个魔数值再 Java 还称做“Oak”语言的时候(大约是 1991 年前后)就已经确定下来了。
紧接着魔数的4个字节储存的是Class文件的版本号:第5和第6个字节是次版本号,第7和第8个字节是主版本号。Java版本号是从45开始的,JDK1.1之后的每个JDK大版本发布主版本号向上加1(JDK 1.0 ~ 1.1 使用了 45.0 ~ 45.3 的版本号),
高版本的 JDK 能向下兼容以前版本的 Class 文件,但不能运行以后版本的 Class 文件,即使文件格式并未发生任何变化,虚拟机也必须拒绝执行超过其版本号的 Class 文件。
例如,JDK 1.1 能支持版本号为 45.0 ~ 45.65535 的 Class 文件,无法执行版本号为 46.0 以上的 Class 文件,而 JDK 1.2 则能支持 45.0 ~ 46.65535 的 Class 文件。 JDK 版本为 1.7,可生成的 Class 文件主版本号最大值为 51.0
就Hello.class文件而言,代表次版本号的第5个和第6个字节为0X0000,而主版本号的值为0X0034,也就是十进制的52,该版本号说明这个文件是可以被jdk1.8或者以上版本的虚拟机执行的class文件,图1-4列出了从jdk1.1到jdk1.8 class文件版本与jdk版本对应的关系
图1-4
待续...
原文:https://www.cnblogs.com/kiwi-deng/p/10931554.html