锁定老帖子 主题:Java类文件格式快速入门
精华帖 (0) :: 良好帖 (3) :: 新手帖 (1) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-07-09
最后修改:2009-07-10
原文地址:http://viralpatel.net/blogs/2009/01/tutorial-java-class-file-format-revealed.html 原作者:Viral Patel 译者:Alan Gao @ cgaolei.iteye.com
译者序: 最近工作解决一个问题时需要用到Java bytecode的知识,临阵磨枪学习了一下,还真的对java bytecode产生的很大的兴趣,打算平时再深入研究一下。学字节码时,我是先从类文件的格式入手的。当然,学习这方面东西,最权威不过的还得是<<Java虚拟机规范了>>:http://java.sun.com/docs/books/jvms/second_edition/html/VMSpecTOC.doc.html。 只不过那里写的过于正规详细,需要一定时间理解和消化。随即搜索了一下相关的文章,于是找到了Viral Patel的这篇教程。文章图文并茂,简单易懂,短短几句话就含盖了重要的知识点,可以让人快速勾画出类文件的轮廓。做为快速入门和大概了解类文件的教程最合适不过了。又搜索了一下中文的资料,相关的文章也不少,但感觉都没有这篇适合。所以翻译一下做为参考。
译文:
我们所看到的Java字节码是被封装在一个类文件中(扩展名为.class)。在这个教程中,就让我们来看看类文件的内部构造。
Java类文件结构示意图:
上图描绘的Java类文件被分为了不同的区段,包括魔术码(magic)、版本(version)、常量池(constant pool)、访问标识(access flags)、(this)类、(super)类、接口(interfaces)、域(fields)、方法(methods)和属性(attributes)。
首先Java类的长度在它被加载之前是未知的,因为类中含有可变长度的区段,如常量池、方法、属性等这些区段。但这些区段的开头字节都是该区段的大小或长度信息,这样JVM在实际装载它们之前会知道这些可变长度区段的大小。写入类文件的数据是以紧凑的单字节存放的,这有助于减小类文件的大小。Java类文件中不同区段的顺序是严格规定的,以便JVM可以按其顺序载入不同区段。让我们详细看看类文件中的每个组成部分。
(译者注:这十个区段M
agic, V
ersion, C
onstant pool, A
ccess flags, T
his, S
uper, I
nterfaces, F
ields, M
ethods, A
ttributes
连起来可以用一个句英文方便记忆它们的顺序:M
y V
ery C
ute A
nimal T
urns S
avage I
n F
ull M
oon A
reas
.
我非常可爱的小动物在滿月的地方变得疯狂。)
版本号(version)区段
紧跟着的四个字节包含了类文件的主要和次要版本号 。版本号数字可使JVM核实并确定类文件是否兼容。如果版本号大于JVM可以加载的版本号,类文件将无法被载入。
(译者注:原文对常量池的描述还缺少一个关键内容:常量池计数的值是常量池中元素总数量+1,元素的下标从1开始。例如图中计数为3,那么真正紧跟着计数只有两个元素,下标为1,2。原文的配图多一个元素,在这里改正)
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-07-10
问题:
1.译者注:虽是16进制编码,但实际是英文单词CAFE BABE 其实这就是无符号数,并不是字符。 2.常量池(constant pool)区段 下面的图错误了吧。常量池number为3的话,常量池中只有两项,下表为1和2. 3.Super类区段 和This类很接近,这两个字节的值也是指向常量池里一个下标,指向的常量值即是指向父类名的字符串。 描述很混、存在问题。this_class部分说的很清楚,这个下表指向的是CONSTANT_Class_info类型常量,而指向字符串的部分是在这个CONSTANT_Class_info常量中。 |
|
返回顶楼 | |
发表时间:2009-07-10
ZangXT 写道 问题:
1.译者注:虽是16进制编码,但实际是英文单词CAFE BABE 其实这就是无符号数,并不是字符。 2.常量池(constant pool)区段 下面的图错误了吧。常量池number为3的话,常量池中只有两项,下表为1和2. 3.Super类区段 和This类很接近,这两个字节的值也是指向常量池里一个下标,指向的常量值即是指向父类名的字符串。 描述很混、存在问题。this_class部分说的很清楚,这个下表指向的是CONSTANT_Class_info类型常量,而指向字符串的部分是在这个CONSTANT_Class_info常量中。 感谢ZangXT的指正: 1. 是我的注释有误导,Magic的值是0xCAFEBABE,我的意思其实是想说这个值16进制的写法正好是英文单词Cafe Babe(咖啡宝贝),以方便记忆。 2. 的确是错的,常量池计数是常量池是项目数加1。图是原文的图,描述中也没有提到这个。我会加上注释更正,但既然是翻译,我应该尽量保留原文描述。 3. 原文中对Super类区段的解释也比较省略,因为有This类区段做参考,两个欧段结构上是相似的,只是指向的内容一个不同。 再次感请ZangXT,我会在正文中做出更正和注释。 |
|
返回顶楼 | |
浏览 4324 次