当前位置: 首页 > 科技观察

JVM深入学习:Java之Class文件流程分析

时间:2023-03-12 20:58:16 科技观察

前言:身为java程序员,怎能不了解JVM?如果你想学习JVM,那么你必须了解Class文件。类用于虚拟机。如鱼得水,虚拟机因Class而有生命。《深入理解java虚拟机》花了整整一章来解释Class文件,但看完之后还是一头雾水,模模糊糊。前段时间刚好看到一本好书:《自己动手写Java虚拟机》,作者用go语言实现了一个简单的JVM。虽然没有完全实现JVM的所有功能,但是对于一些对JVM稍有兴趣的人来说,可读性还是很高的。作者讲解的很详细,每个过程都分一个章节,其中一部分是讲解如何解析Class文件。这本书不算厚,很快就看完了。读后,收获颇丰。但是后来终于明白纸上谈兵浅薄,知道这件事必须要做,于是尝试自己解析Class文件。go语言虽然优秀,但毕竟不精通,尤其不习惯把类型放在变量后面的语法。还是老老实实用java比较好。话不多说,先贴出项目地址:https://github.com/HalfStackDeveloper/ClassReaderClass文件什么是Class文件?java之所以能做到跨平台,是因为它的编译阶段不是直接将代码编译成平台相关的机器语言,而是先编译成二进制java字节码,放到Class文件中,再把类加载到虚拟机文件,解析出程序运行所需要的内容。每个类都会被编译成一个单独的class文件,内部类也会作为一个独立的类来生成自己的类。基本结构就是随便找一个class文件,用SublimeText打开是这样的:是不是一脸懵逼,不过java虚拟机规范中给出了class文件的基本格式,只要是按照这种格式解析:ClassFile{u4magic;u2次要版本;u2主要版本;u2constant_pool_count;cp_infoconstant_pool[constant_pool_count-1];u2访问标志;u2这个类;u2超类;u2接口数;u2接口[interfaces_count];u2字段数;field_info字段[fields_count];u2方法计数;method_info方法[methods_count];u2属性计数;attribute_infoattributes[attributes_count];}ClassFile中的字段类型是u1,u2,u4,这是什么类型?其实很简单,分别表示1个字节,2个字节,4个字节。前四个字节为:Magic,用于唯一标识文件格式,一般称为幻数(magicnumber),让虚拟机识别加载的文件是否为class格式,幻数为类文件是cafebabe。不仅仅是类文件,基本上大多数文件都有幻数来标识自己的格式。接下来的部分主要是class文件的一些信息,比如常量池、类访问标志、父类、接口信息、字段、方法等,具体信息可以参考。分析字段类型上面提到,ClassFile中的字段类型有u1、u2、u4,分别表示1字节、2字节、4字节的无符号整数。java中的short、int、long分别是2、4、8字节的有符号整数,去掉符号位,正好可以用来表示u1、u2、u4。publicclassU1{publicstaticshortread(InputStreaminputStream){byte[]bytes=newbyte[1];尝试{inputStream.read(bytes);}catch(IOExceptione){e.printStackTrace();}短值=(short)(bytes[0]&0xFF);返回值;}}publicclassU2{publicstaticintread(InputStreaminputStream){byte[]bytes=newbyte[2];尝试{inputStream.read(bytes);}catch(IOExceptione){e.printStackTrace();}整数=0;for(inti=0;i