首页 > Linux操作系统 > Linux操作系统 > class文件的结构(二)
Alzhu.San
本文介绍class文件的接口表,字段表,方法表,着重介绍属性表。
在上一篇文章(class文件的结构(一) )中,我们介绍了class文件的总体结构,并着重介绍了常量池。在这篇文章中将补全其他结构。
首先我们补全上一个例子。
//A.java文件
import java.io.Serializable;
class A implements Serializable
{
private double m_x;
public void setX(double x)
{
m_x = x;
}
public double getX()
{
return m_x;
}
}
类A实现了Serializable接口,并增加了一个字段m_x,增加了两个方法
public void setX(double x)
public double getX()
下面是其class文件。
0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000h: CA FE BA BE 00 00 00 32 00 17 0A 00 04 00 12 09 ;漱壕...2........
00000010h: 00 03 00 13 07 00 14 07 00 15 07 00 16 01 00 03 ;................
00000020h: 6D 5F 78 01 00 01 44 01 00 06 3C 69 6E 69 74 3E ;m_x...D...
00000030h: 01 00 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F ;...()V...Code...
00000040h: 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 ;LineNumberTable.
00000050h: 00 04 73 65 74 58 01 00 04 28 44 29 56 01 00 04 ;..setX...(D)V...
00000060h: 67 65 74 58 01 00 03 28 29 44 01 00 0A 53 6F 75 ;getX...()D...Sou
00000070h: 72 63 65 46 69 6C 65 01 00 06 41 2E 6A 61 76 61 ;rceFile...A.java
00000080h: 0C 00 08 00 09 0C 00 06 00 07 01 00 01 41 01 00 ;.............A..
00000090h: 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 ;.java/lang/Objec
000000A0h: 74 01 00 14 6A 61 76 61 2F 69 6F 2F 53 65 72 69 ;t...java/io/Seri
000000B0h: 61 6C 69 7A 61 62 6C 65 00 20 00 03 00 04 00 01 ;alizable. ......
000000C0h: 00 05 00 01 00 02 00 06 00 07 00 00 00 03 00 00 ;................
000000D0h: 00 08 00 09 00 01 00 0A 00 00 00 1D 00 01 00 01 ;................
000000E0h: 00 00 00 05 2A B7 00 01 B1 00 00 00 01 00 0B 00 ;....*?.?......
000000F0h: 00 00 06 00 01 00 00 00 04 00 01 00 0C 00 0D 00 ;................
00000100h: 01 00 0A 00 00 00 22 00 03 00 03 00 00 00 06 2A ;......"........*
00000110h: 27 B5 00 02 B1 00 00 00 01 00 0B 00 00 00 0A 00 ;'?.?..........
00000120h: 02 00 00 00 09 00 05 00 0A 00 01 00 0E 00 0F 00 ;................
00000130h: 01 00 0A 00 00 00 1D 00 02 00 01 00 00 00 05 2A ;...............*
00000140h: B4 00 02 AF 00 00 00 01 00 0B 00 00 00 06 00 01 ;?.?...........
00000150h: 00 00 00 0D 00 01 00 10 00 00 00 02 00 11 ;..............
第一块加蓝的部分为常量池,前文已有叙述,由于我们增加了类A中的内容,常量池中也增加了一些项目,常量池中的常量字串是用Unicode表示的可以在上表的最由一栏看到其对应的字符串,上表也是一般的16进制编辑器的呈现形式,常量池一般在最后一个常量字串后结束,这也是识别常量池结束位置的方法。
绿色标记的部分是接口表,它很简单前两个字节表示后面将引导几个接口内容(这里是0x0001表示后面有一个接口),后面每2字节表示一个接口,用索引形式指向在常量池中的接口全限定名(此处指向0x0005(java/io/Serializable))。
红色部分是字段表前两个字节表示后面将引导几个字段表项(这里是0x0001表示后面有一个字段表项),后面紧接着若干个字段表项。每一个字段表项按下面的方式构成:
class文件有包含属性表,字段表项中有包含属性表,方法表项中也包含属性表,尤其重要的是代码段也包含在属性表中,属性表是十分重要的一项。每一个属性表由由以下几部分组成
如上例中字段m_x的属性表只包含表头(0x0000)表示没有属性
文件的属性表(最后一行黑色部分)表头为0x0001表示有1个属性,其后是其表项:键为指向常量池中序号为0x0010的项目(SourceFile)属性表的长度为2字节,值为指向常量池中序号为0x0011的项目(A.java)
值如何安排取决于键的类型:有的直接指向常量池中的一项如文件的SourceFile属性,有的结构就会比较复杂如Code属性。
上例中包含了Code及LineNumberTable两种属性下面对它们值的组织情况分别给予说明:
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/15822571/viewspace-466118/ ,如需转载,请注明出处,否则将追究法律责任。