Java二进制字节码文件解析

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

解读字节码文件

二进制类格式实际上是由 JVM 规范定义的。通常这些类表示是由编译器从 Java 语言源代码生成的,而且它们通常存储在扩展名为 .class 的文件中。但是,这些特性都无关紧要。就 JVM 而言,重要的部分不是源代码以及如何存储源代码,而是格式本身。下面我们看一段Java 的源代码,我们将分析它生成的字节码文件。 package Other;

class Test{

void print(PassTest test){ test.a=10;

test=new PassTest(); test.a=20; } }

上述源代码经过编译器编译之后便会生成一个字节码文件,字节码是一种二进制的类文件,它的内容是JVM 的指令,而不像C 、C++经由编译器直接生成机器码。我们不用担心生成的字节码文件的兼容性,因为所有的JVM 全部遵守Java 虚拟机规范,也就是说所有的JVM 环境都是一样的,这样一来字节码文件可以在各种JVM 上运行。

由于字节码文件为二进制格式,因此阅读十分不便,这里我为大家介绍一款阅读字节码文件的软件“ClassLib ”,可以在/download/jclasslib/files.html 得到下载,该软件为免费软件,不需要注册。该软件将二进制数据转化为文本数据,方便阅读。

使用该软件打开上述编译好的字节码文件,如图:

杨迪

数字签名人 杨迪DN :cn=杨迪,c=CN-中国,

email=yyyyttttwwww@ 原因:我是该文档的作者位置:沈阳日期:2006.10.03 21:49:23 +08'00'

让我们瞧一瞧字节码中究竟写了些什么东西,首先左面的树型结构第一个是General Information(概述信息),其中的详细信息见界面中部区域。前两个信息分别是Minor version (次要版本)和Major version(主要版本),两个版本指的是Java类格式的版本号。如果你想知道你的环境信息可以参考如下内容。

System.getProperty(String)可以获得环境信息,它会根据参数不同获取不同的环境信息。

属性名描述

java.version Java 运行时版本

java.home Java 的安装目录

java.class.version Java 类格式的版本号

java.class.path Java

类的查找路径

java.io.tmpdir 默认的临时目录

piler Java 所使用的及时编译器

java.ext.dirs Java 扩展包的目录

操作系统的名称

os.arch 操作系统的体系结构

os.version 操作系统的版本

file.separator 文件分隔符(Unix 下为"/")

path.separator 路径分隔符(Unix 下为":")

line.separator 换行符(Unix 下为"\n")

用户帐号名

user.home 用户目录

user.dir 用户当前的工作目录

所以说System.getProperty(“java.class.version”)就能获取到当前系统的Java类版本。

言归正传,字节码的Java类版本是49.0。Constant Pool Count(常量池总数)的值是36,常量池里放着类定义所用的所有常量。它包括类名和方法名、特征符以及字符串,还有各种二进制值。常量池中各项的长度是可变的,每项的第一个字节标识项的类型以及对它解码的方式。这里我不详细探究所有这些内容的细节,如果感兴趣,有许多可用的的参考资料。关键之处在于常量池还包含该类所使用的其它类和方法的所有引用,还包含了该类及其方法的实际定义。常量池往往占到二进制类大小的一半或更多,但是每一个常量项占用的空间却不大,因为常量池中含有很多的常量项。

Access Falgs的值是0x0021,意味着这个类的访问权限是public。

This Class的内容是“cp_info_#4”,cp代表的是常量池;info的意思是常量项;#4代表第四号常量项。This Class:cp_info_#4的这个意思是说:这个类的信息保存在了常量池的第四个常量项中。从下面的图片看到常量池中第四个常量项保存的内容是Class name:cp_info_#28,也就是说类名被保存到了常量池的第28个常量项中。常量池中的第28号常量项的内容为Length of byte array:12;Length of string:8;String:循环语句/For。我们先来看看String:循环语句/For这条信息,它说明类的信息为“循环语句”包中的“For”类。“循环语句/For”字符串的长度为8个字符,所以Length of string:8记录了这一点。通常我们知道一个汉字占用两个byte,字母占用一个byte。“循环语句/For”正好是12个byte,Length of byte array:12说明了这一点,那么整个这一条常量项的信息都明朗了。

Super Class :cp_info_#5说明这个类的超类信息保存在第5号常量项之中。第5号常量项的内容为Class name :cp_info_#29,也就是说超类信息保存在第29个常量项里。29号常

量项内容是Length of byte array:16;Length of string:16;String:java/lang/Object。

这次阅读这些信息对于我们就有经验了,超类是ng.Object,字符串长度16字符,字符串占用空间16字节。

再次回到General Information,见下图。

Interfaces count:0说明类没有扩展接口。Fields counts:0说明类中没有定义成员变量。Methods counts:2指出类中有两个方法。可能这里你会有疑问:很明显类中只定义了一个主方法。顺便提醒你,类中还有一个默认的构造器,恍然大悟了吧。Attribute count:1的意思是类格式的属性。

由于该类既没有扩展借口,又没有定义成员变量,所以树型结构的Fields和Interfaces 没有数据,因此跳过这一部分,我们直接看Methods树型结构,见下图,Method中有

和main两项

相关文档
最新文档