深入分析Java Web技术内幕读书笔记
chapter5. 深入class文件结构
Java“一次编译到处运行”的根本因素—java文件编译成class文件就可以在通过JVM运行;
Java语言中的变量、关键字、类名等等的语义都是由多条字节码命令组合而成的。
5.1 JVM指令集
5.1.1 与类相关的指令
oolong编程语言是一种汇编语言,我们可以将class文件先转化为oolong汇编语言,以便理解。实际上JVM直接基于字节码运行,不需要经过中间的汇编过程,但是我们依然可以先把它翻译成汇编,这些汇编代码可以很好地对应JVM提供的指令集。
JVM中的指令:
- .source Message.java表示这个代码的源文件是Message.java;
- .class public Message表示这是一个类且共有的类名是Message;
- .super java/lang/Object表示这个类的父类是Object;
- 类的修饰符与Java的一一对应,如public、final等;
这部分指令主要与类信息相关,譬如原文件名,类名,父类,以及修饰符等等,一般类中的操作都有对应的JVM指令相对应(这里的指令指的是汇编指令)
5.1.2 方法的定义
方法的定义包括修饰符,方法名,操作函数等等,也有其对应的指令。比如invokervirtual调用实例方法。
具体示例:.method public () V,这是一个公有方法,没有参数,返回值类型为V(即void),表示的是构造函数;
再如:.method public static main ([Ljava/lang/String;] V)表示的是main方法,它的参数是一个string类型的数组,“[]”表示的是main方法,而“L”表示的是一个类形式而不是基本数据类型(如int、long等),凡是L表示的类后面都会以“;”结尾,表示这个类的结束;
5.1.3 属性的定义
属性定义包括了数据类型,方法的修饰属性,类的修饰属性,等等。
5.1.4 其他指令集
由于JVM的指令集是基于栈进行操作的,所以也有与栈操作相关的指令集,还有与运算相关,与数组操作相关的指令集等等。
这里也有我们熟悉的同步操作相关指令集,monitor enter和monitor out,这个汇编指令可以帮助jvm完成同步操作。
5.2 class文件头的表现形式
class文件的内容是顺序排列的。
第一行是一个标识符,是”cafebabe”,表明这个文件是一个class文件。
后面两个字节表示版本分为。
所以前6个字节是表示class文件的基本头信息,jvm加载class时会检查其是否符合条件。
5.3 常量池
第一行有两个字节表示该类中含有常量的总数,有十几种类型。
这些常量通常都是相互引用的。
基本数据类型
Integer,Float,Long等等。
5.3.1 UTF-8常量类型
一般用于存储字符串值。
5.3.2 Fieldref、Methodref类型
这两个类型很是为了描述class中的属性项和方法的,可以根据代码常量的二进制数表示,比如fieldref,前一个字节表示这个常量是Filedref类型,前两个字节表示是哪个类中的field,后面两个字节表示这个fieldref的name和type。
methodref和fieldref也类似。
所以methodref和fieldref存的是类名称和nameandtype。