《Java虚拟机原理图解》1.4 class文件中的字段表集合--field字段在class文件中是怎样组织的

0.前言

了解JVM虚拟机原理是每一个Java程序员修炼的必经之路。但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述,很难给人以形象化的认知,看完之后感觉还是稀里糊涂的。

感于以上的种种,我打算把我在学习JVM虚拟机的过程中学到的东西,结合自己的理解,总结成《Java虚拟机原理图解》 这个系列,以图解的形式,将抽象的JVM虚拟机的知识具体化,希望能够对想了解Java虚拟机原理的的Java程序员 提供点帮助。

读完本文,你将会学到:

1、类中定义的field字段是如何在class文件中组织的

2、不同的数据类型在class文件中是如何表示的

3、static final类型的field字段的初始化赋值问题

1.概述

字段表集合是指由若干个字段表(field_info)组成的集合。对于在类中定义的若干个字段,经过JVM编译成class文件后,会将相应的字段信息组织到一个叫做字段表集合的结构中,字段表集合是一个类数组结构,如下图所示:

注意:这里所讲的字段是指在类中定义的静态或者非静态的变量,而不是在类中的方法内定义的变量。请注意区别。

比如,如果某个类中定义了5个字段,那么,JVM在编译此类的时候,会生成5个字段表(field_info)信息,然后将字段表集合中的字段计数器的值设置成5,将5个字段表信息依次放置到字段计数器的后面。

2. 字段表集合在class文件中的位置

字段表集合紧跟在class文件的接口索引集合结构的后面,如下图所示:

3. Java中的一个Field字段应该包含那些信息?------字段表field_info结构体的定义

针对上述的字段表示,JVM虚拟机规范规定了field_info结构体来描述字段,其表示信息如下:

下面我将一一讲解FIeld_info的组成元素:访问标志(access_flags)名称索引(name_index)描述索引(descriptor_index)属性表集合

4. field字段的访问标志

如上图所示定义的field_info结构体,field字段的访问标志(access_flags)占有两个字节,它能够表述的信息如下所示:

举例:如果我们在某个类中有定义field域:private
static String str;,那么在访问标志上,第15ACC_PRIVATE和第13ACC_STATIC标志位都应该为1。fieldstr的访问标志信息应该是如下所示:

如上图所示,str字段的访问标志的值为0x000A,它由两个修饰符ACC_PRIVATEACC_STATIC组成。

根据给定的访问标志(access_flags),我们可以通过以下运算来得到这个域有哪些修饰符:

上面列举的str字段的访问标志的值为000A,那么分别域上述的标志符的特征值取&,结果为1的只有ACC_PRIVATEACC_STATIC,所以该字段的标志符只有有ACC_PRIVATEACC_STATIC

5. 字段的数据类型表示和字段名称表示

class文件对数据类型的表示如下图所示:

field字段名称,我们定义了一个形如private static String strfield字段,其中"str"就是这个字段的名称。

class文件将字段名称和field字段的数据类型表示作为字符串存储在常量池中。在field_info结构体中,紧接着访问标志的,就是字段名称索引和字段描述符索引,它们分别占有两个字节,其内部存储的是指向了常量池中的某个常量池项的索引,对应的常量池项中存储的字符串,分别表示该字段的名称和字段描述符。

6.属性表集合-----静态field字段的初始化

在定义field字段的过程中,我们有时候会很自然地对field字段直接赋值,如下所示:

	public static final int MAX=100;
	public  int count=0;

对于虚拟机而言,上述的两个field字段赋值的时机是不同的:

  • 对于非静态(即无static修饰)的field字段的赋值将会出现在实例构造方法<init>()
  • 对于静态的field字段,有两个选择:1、在静态构造方法<cinit>()中进行;2
    、使用ConstantValue属性进行赋值

Sun javac编译器对于静态field字段的初始化赋值策略

目前的Sun javac编译器的选择是:如果使用final
static同时修饰一个field字段,并且这个字段是基本类型或者String类型的,那么编译器在编译这个字段的时候,会在对应的field_info结构体中增加一个ConstantValue类型的结构体,在赋值的时候使用这个ConstantValue进行赋值;如果该field字段并没有被final
修饰,或者不是基本类型或者String类型,那么将在类构造方法<cinit>()中赋值。

对于上述的public static final init MAX=100;   javac编译器在编译此field字段构建field_info结构体时,除了访问标志、名称索引、描述符索引外,会增加一个ConstantValue类型的属性表。

7.实例解析:

定义如下一个简单的Simple类,然后通过查看Simple.class文件内容并结合javap
-v Simple
生成的常量池内容,分析str field字段的结构:

package com.louis.jvm;

public class Simple {

	private  transient static final String str ="This is a test";
}

注:

1. 字段计数器中的值为0x0001,表示这个类就定义了一个field字段

2. 字段的访问标志0x009A,二进制是00000000 10011010,即第9、12、13、15位标志位为1,这个字段的标志符有:ACC_TRANSIENT、ACC_FINAL、ACC_STATIC、ACC_PRIVATE;

3. 名称索引中的值为0x0005,指向了常量池中的第5项,为“str”,表明这个field字段的名称是str

4. 描述索引中的值为0x0006,指向了常量池中的第6项,为"Ljava/lang/String;",表明这个field字段的数据类型是java.lang.String
类型;

5.属性表计数器中的值为0x0001,表明field_info还有一个属性表;

6.属性表名称索引中的值为0x0007,指向常量池中的第7项,为“ConstantValue”,表明这个属性表的名称是ConstantValue,即属性表的类型是ConstantValue类型的;

7.属性长度中的值为0x0002,因为此属性表是ConstantValue类型,它的值固定为2

8.常量值索引 中的值为0x0008,指向了常量池中的第8项,为CONSTANT_String_info类型的项,表示“This is a test” 的常量。在对此field赋值时,会使用此常量对field赋值。

作者的话

本文是《Java虚拟机原理图解》系列的其中一篇,如果您有兴趣,请关注该系列的其他文章~

觉得本文不错,顺手点个赞哦~~您的鼓励,是我继续分享知识的强大动力!

-----------------------------------------------------------------------------------------------------------------------------------------

                                                                              本文源自  http://blog.csdn.net/luanlouis/,如需转载,请注明出处,谢谢!

时间: 2024-10-05 15:37:08

《Java虚拟机原理图解》1.4 class文件中的字段表集合--field字段在class文件中是怎样组织的的相关文章

《Java虚拟机原理图解》1.5、 class文件中的方法表集合--method方法在class文件中是怎样组织的

0. 前言 了解JVM虚拟机原理是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述,很难给人以形象化的认知,看完之后感觉还是稀里糊涂的. 感于以上的种种,我打算把我在学习JVM虚拟机的过程中学到的东西,结合自己的理解,总结成<Java虚拟机原理图解> 这个系列,以图解的形式,将抽象的JVM虚拟机的知识具体化,希望能够对想了解Java虚拟机原理的的Java程序员 提供点帮助.

《Java虚拟机原理图解》6、 class文件中的方法表集合--method方法在class文件中是怎样组织的

0. 前言 了解JVM虚拟机原理是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述,很难给人以形象化的认知,看完之后感觉还是稀里糊涂的. 感于以上的种种,我打算把我在学习JVM虚拟机的过程中学到的东西,结合自己的理解,总结成<Java虚拟机原理图解> 这个系列,以图解的形式,将抽象的JVM虚拟机的知识具体化,希望能够对想了解Java虚拟机原理的的Java程序员 提供点帮助.

Java虚拟机原理图解-- 1.2.2、Class文件中的常量池详解(上)[转]

NO1.常量池在class文件的什么位置? 我的上一篇文章<Java虚拟机原理图解> 1.class文件基本组织结构中已经提到了class的文件结构,在class文件中的魔数.副版本号.主版本之后,紧接着就是常量池的数据区域了,如下图用红线包括的位置: 知道了常量池的位置后,然后让我们来揭秘常量池里究竟有什么东西吧- NO2.常量池的里面是怎么组织的? 常量池的组织很简单,前端的两个字节占有的位置叫做常量池计数器(constant_pool_count),它记录着常量池的组成元素  常量池项(

Java虚拟机原理图解-- 1.1、class文件基本组织结构 [转]

作为Java程序猿,我们知道,我们写好的.java 源代码,最后会被Java编译器编译成后缀为.class的文件,该类型的文件是由字节组成的文件,又叫字节码文件.那么,class字节码文件里面到底是有什么呢?它又是怎样组织的呢?让我们先来大概了解一下他的组成结构吧. NO1. 魔数(magic) 所有的由Java编译器编译而成的class文件的前8个字节都是“0xCAFEBABE”        它的作用在于:当JVM在尝试加载某个文件到内存中来的时候,会首先判断此class文件有没有JVM认为

Java虚拟机原理图解-- 1.2、class文件中的常量池

了解JVM虚拟机原理 是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述,很难给人以形象化的认知,看完之后感觉还是稀里糊涂的.感于以上的种种,我打算把我在学习JVM虚拟机的过程中学到的东西,结合自己的理解,总结成<Java虚拟机原理图解> 这个系列,以图解的形式,将抽象的JVM虚拟机的知识具体化,希望能够对想了解Java虚拟机原理的的Java程序员 提供点帮助. 上一章节&l

《Java虚拟机原理图解》 1.2.2、Class文件里的常量池具体解释(上)

[last updated:2014/11/27] NO1.常量池在class文件的什么位置? 我的上一篇文章<Java虚拟机原理图解> 1.class文件基本组织结构中已经提到了class的文件结构,在class文件里的魔数.副版本号号.主版本号之后,紧接着就是常量池的数据区域了,例如以下图用红线包含的位置: 知道了常量池的位置后,然后让我们来揭秘常量池里到底有什么东西吧- NO2.常量池的里面是怎么组织的? 常量池的组织非常easy,前端的两个字节占有的位置叫做常量池计数器(constan

《Java虚拟机原理图解》 1.2.3、Class文件里的常量池具体解释(下)

NO9.类中引用到的field字段在常量池中是如何描写叙述的?(CONSTANT_Fieldref_info, CONSTANT_Name_Type_info) 一般而言.我们在定义类的过程中会定义一些 field 字段.然后会在这个类的其它地方(如方法中)使用到它.有可能我们在类的方法中仅仅使用field字段一次.也有可能我们会在类定义的方法中使用它非常多非常多次. 举一个简单的样例.我们定一个叫Person的简单java bean,它有name和age两个field字段,例如以下所看到的:

《Java虚拟机原理图解》1.3、class文件中的访问标志、类索引、父类索引、接口索引集合

讲完了class文件中的常量池,我们就相当于克服了class文件中最麻烦的模块了.现在,我们来看一下class文件中紧接着常量池后面的几个东西:访问标志.类索引.父类索引.接口索引集合. 1. 访问标志.类索引.父类索引.接口索引集合 在class文件中的位置 好,让我们来一一击破它们,看看它们到底是什么东西. 2. 访问标志(access_flags)能够表示什么? 访问标志(access_flags)紧接着常量池后,占有两个字节,总共16位,如下图所示: 当JVM在编译某个类或者接口的源代码

《Java虚拟机原理图解》 2、class文件中的常量池

了解JVM虚拟机原理 是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述,很难给人以形象化的认知,看完之后感觉还是稀里糊涂的.感于以上的种种,我打算把我在学习JVM虚拟机的过程中学到的东西,结合自己的理解,总结成<Java虚拟机原理图解> 这个系列,以图解的形式,将抽象的JVM虚拟机的知识具体化,希望能够对想了解Java虚拟机原理的的Java程序员 提供点帮助. 上一章节&l