1.字段表字段表跟在接口表索引之后。字段表包括访问令牌、字段名索引、描述符索引和属性表。属性表包括属性计数器以这段代码为例:packagecom.yang.testField;publicclassMain{privatevolatileinta=1;publicstaticfinalStringb="abc";}十六进制数据如下图所示:可以看出字段计数为0x0002,因为有2个字段,a和b。字段a的访问标志为0x0042,用该值与标识符的特征值取AND,结果为1则表示该字段有对应的标识符。字段标识如下:这里我们可以得出a的访问标志为ACC_PRIVATE和ACC_VOLATILE。a的名称索引为0x0005,我们看一下常量池:可以得出第一个字段的名称索引指向常量池中的第五个常量项,即“a”。a的描述符索引为0x0006,也就是常量池中的“I”。完成的字段类型和描述符对照表如下:接下来是a的属性计数器,对应的值为0x0000,表示a没有属性表。在b字段表中粘贴属性表:b的属性计数器为0x0001,表示存在属性表。属性表中只有一个元素,即0x0009。在常量池中显示为ConstantValue,说明该属性为ConstantValue类型,属性长度为2,属性值索引为0x000A,即在常量池中查找#11,然后查找#21,原来是字符串“abc”。为什么inta没有属性表,而staticfinalb有属性表?这就要从字段的赋值策略说起:对于一个实例字段,比如这里的a,赋值阶段发生在对象实例的构造方法中,即;对于非final静态字段,初始值的赋值会发生在解析阶段,用户指定值的赋值会发生在初始化阶段,在类的构造方法中完成,即。对于一个final静态字段,它是基本类型或者String类型,在编译时为该变量赋一个用户指定的值,在常量池中形成一个ConstantValue类型的属性,该属性值为常量的值.如果是String类型以外的引用类型,则赋值操作在初始化阶段完成。下面举例说明:packagecom.yang.testField;publicclassMain{privatevolatileinta=1;publicstaticfinalStringb="abc";publicstaticStringc="def";publicstaticThreadd=newThread();赋值操作。方法中的情况:这里做的是对普通静态变量c和非String引用类型变量d的赋值操作。pair和method的更多理解可以参考这篇Java执行顺序深入理解clinit和init2,方法表后面跟着字段表就是方法表,方法表类似于字段表,方法表包括方法计数、访问标记、名称索引、描述符索引、属性表,其中属性表还包括属性计数和属性集合。方法count和nameindex这里就不解释了。方法的访问标志是:下面是一个简单的例子:packagecom.yang.testMethod;publicclassMain{publicMain(){}privateintgetInt(intk){returnk;}publicstaticThreadgetThread(inti,doubled,Runnablerunnable){System.out.println(i*d);returnnewThread(runnable);}}构造函数的描述符为()VgetInt方法的描述符为(I)IgetThread方法的描述符为(IDLjava/lang/Runnable;)Ljava/lang/Thread;从这里,我们可以看出方法描述符是这样组织的:(参数列表中字段的描述符)返回值的描述符接下来我们将讨论方法的属性表。前面提到,属性表包含属性计数与属性集合类似,属性集合包含属性名称索引+属性长度+属性值。属性表中最重要的属性是代码属性。Code属性中有几个重要的东西:字节码、LineNumberTable行号表、LocalVariableTable局部变量表、ExceptionTable异常表。以下面的代码为例:publicstaticThreadgetThread(inti,doubled,Runnablerunnable){try{System.out.println(i*d);}catch(Exceptione){returnull;}returnnewThread(runnable);}字节码最重要class文件里的东西,jvm主要是提取字节码执行。LineNumberTable维护了java源码和字节码的对应关系:LocalVariableTable记录了局部变量的描述:关于局部变量表的详细介绍可以参考我的另一篇文章虚拟机栈的Viscera。ExceptionTable会告诉虚拟机异常处理逻辑,比如下图中的异常表,表示如果0行到10行的字节码出现类型类型的异常,就会跳转到13行的字节码去过程。
