java虚拟机之class文件解读

java虚拟机之class文件解读

解读前提

我们知道,java的源码文件经过编译器的编译就得到了字节码文件,也就是class文件。我们一直以来,关心的都是源码文件。身为程序员的你,是否跟我一样好奇过class文件里面是什么,是否也打开过class文件,然后发现一堆看不懂的乱码而放弃。那么这篇博客就是介绍如何来解读class文件。
首先我们要知道class文件的内容是以二进制的格式存在的,这也就是为什么我们用一些工具打开这些文件的时候,会出现乱码的根源。因为这些工具尝试将class文件的内容用一些给定的编码进行解析,比如UTF-8、GBK等,这样子解析出来的内容必然是没有意义乱码。
那么我们该如何来查看class文件的内容?
总的思想就是,将二进制的内容转换成十六进制进行查看。原因是,class文件的内容都是字节流组成的,一个字节有八位。16位、32位、64位的数据将使用2个、4个、8个字节来表示。一个字节的内容转换成十六进制,就是两位,方便观看。关于这一步,有比较多的方法,我这里使用的是使用Editplus的Hex Viewer来查看。

  • 使用Editplus打开class文件,提示是否选择另外一种编码,点击是
    在这里插入图片描述
  • 在编码选择窗口中,选择Hex Viewer,并点击OK
    在这里插入图片描述
  • 现在我们看到的内容就是16进制的。最左边的内容表示一行开始的偏移量。例如:CA的偏移量为00000000,那么FE的偏移量为00000001,直到第一行的最末尾,07的偏移量为0000000F。第二行开始00的偏移量为00000010,由此可见,这个偏移量也是十六进制的。其实这个偏移量也就是字节的索引位置。记住,两个十六进制为一个字节。
    在这里插入图片描述

解读第一步,弄清楚class文件的整体结构

class文件的内容可不是随意组织的,Java虚拟机规范里面对class文件的结构进行的规定。每个class文件对应如下所示的ClassFile结构。

ClassFile {
	u4	magic;
    u2	minor_version;
    u2	major_version;
    u2	constant_pool_count;
    cp_info	constant_pool[constant_pool_count-1];
    u2	access_flags;
    u2	this_class;
    u2	super_class;
    u2	interfaces_count;
    u2	interfaces[interfaces_count];
    u2	fields_count;
    field_info	fields[fields_count];
    u2	methods_count;
    method_info	methods[methods_count];
    u2	attributes_count;
    attribute_info	attributes[attributes_count];	
}

看不懂什么意思没关系,这是很正常的,接着看下去,我会对ClassFile进行解释。这里有一点要先跟大家说明。就是ClassFile结构中的u2、u4分别代表的是2个字节、4个字节,如果后面的内容中出现了类似的结构,也是以此类推,比如u1表示1个字节u8表示8个字节

解读第二步 ClassFile文件解释

魔数

百度百科上对魔数的解释是:
在这里插入图片描述
根据ClassFile结构,我们可以知道,class文件的开始是一个由四个字节长组成的魔数

u4	magic;

表现在class文件中,则如下所示:
在这里插入图片描述
由此我们可以知道,class文件以魔数CA FE BA BE开始,Java虚拟机辨别它为class文件。如果不相信,可以打开多个class文件进行确认,每个class文件的前四个字节都是CA FE BA BE,不会改变。

副版本号

紧接在魔数之后的,是用两个字节表示的副版本号。在魔数跟副版本号之间,没有任何间隔。

u2	minor_version;

在class文件中表示为:
在这里插入图片描述
由此可知,这个class文件的副版本号为0。

主版本号

紧接在副版本号之后的是主版本号,主版本号同样也是用两个字节表示。

u2	major_version;

在class文件中表示为:
在这里插入图片描述
由此可知,主版本号为0034,因为这是16进制的,转换成十进制就是52。JDK的版本跟class版本对应关系如下,由此可知,这个class文件由1.8版本的JDK编译得来。

JDK版本classs版本
JDK 1.852
JDK 1.751
JDK 1.650
JDK 1.549
JDK 1.448
JDK 1.347
JDK 1.246
JDK 1.145

参考书籍

Java虚拟机规范(JavaSE7)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值