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编译器的选择是:假设使用finalstatic同一时候修饰一个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赋值。

8.您还须要了解什么

简单地说,对于一个类而言,它有两部分组成:field字段
method方法。本文主要介绍了field字段,那还剩些一个method方法method方法啦。method方法但是说是class文件里最为重要的一部分了。它包括了方法的实现代码,即机器指令,机器指令是整个class文件的核心,假设你想了解method方法和其内的机器指令
是怎样在class文件里组织的。请看下文

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

作者的话

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

认为本文不错,顺手点个赞哦~~您的鼓舞,是我继续分享知识的强大动力。

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

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

《Java虚拟机原理图解》1.4 class文件里的字段表集合--field字段在class文件里是如何组织的的更多相关文章

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

    0.前言 了解JVM虚拟机原理是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述 ...

  2. 转载---class文件中的字段表集合--field字段在class文件中是怎样组织的

    写的太好了! https://blog.51cto.com/1459294/1932331

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

    0. 前言 了解JVM虚拟机原理是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描 ...

  4. 《Java虚拟机原理图解》 1.2、class文件里的常量池

    [最新更新:2014/11/11]  了解JVM虚拟机原理 是每个Java程序猿修炼的必经之路. 可是因为JVM虚拟机中有非常多的东西讲述的比較宽泛.在当前接触到的关于JVM虚拟机原理的教程或者博客中 ...

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

    [last updated:2014/11/27] NO1.常量池在class文件的什么位置? 我的上一篇文章<Java虚拟机原理图解> 1.class文件基本组织结构中已经提到了clas ...

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

    讲完了class文件里的常量池,我们就相当于克服了class文件里最麻烦的模块了.如今,我们来看一下class文件里紧接着常量池后面的几个东西:訪问标志.类索引.父类索引.接口索引集合. 1. 訪问标 ...

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

    讲完了class文件中的常量池,我们就相当于克服了class文件中最麻烦的模块了.现在,我们来看一下class文件中紧接着常量池后面的几个东西:访问标志.类索引.父类索引.接口索引集合. 1. 访问标 ...

  8. 《Java虚拟机原理图解》 1.2.2、Class文件中的常量池详解(上)

    我的上一篇文章<Java虚拟机原理图解> 1.class文件基本组织结构中已经提到了class的文件结构,在class文件中的魔数.副版本号.主版本之后,紧接着就是常量池的数据区域了,如下 ...

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

    了解JVM虚拟机原理 是每一个Java程序员修炼的必经之路.但是由于JVM虚拟机中有很多的东西讲述的比较宽泛,在当前接触到的关于JVM虚拟机原理的教程或者博客中,绝大部分都是充斥的文字性的描述,很难给 ...

随机推荐

  1. .net 中序列化和反序列化的使用

    序列化的目的:将对象状态转换为可保持或传输的格式的过程.与序列化相对的是反序列化,它将流转换为对象.这两个过程结合起来,可以轻松地存储和传输数据. 序列化 序列化分为JSON 序列化,XML序列化,二 ...

  2. 从BufferedImage到InputStream,实现绘图后进行下载(生成二维码图片并下载)

    @SuppressWarnings("resource") public void download() throws Exception{ String filename = & ...

  3. 数据库的事务处理必须满足ACID原则,ACID分别是指什么

    http://blog.csdn.net/dingxingmei/article/details/39270375

  4. UIWebView加载不了页面, 但在电脑的浏览器上可以打开

    经排查, 系因为URL中包含有中文, 所以无法加载页面, 解决方法如下: 将URL进行转码 NSString *urlStr =[[NSString stringWithFormat:@"h ...

  5. MySQL 表子查询

    MySQL 表子查询 表子查询是指子查询返回的结果集是 N 行 N 列的一个表数据. MySQL 表子查询实例 下面是用于例子的两张原始数据表: article 表: aid title conten ...

  6. 信息增益(IG,Information Gain)的理解和计算

    决策树构建中节点的选择靠的就是信息增益了. 信息增益是一种有效的特征选择方法,理解起来很简单:增益嘛,肯定是有无这个特征对分类问题的影响的大小,这个特征存在的话,会对分类系统带来多少信息量,缺了他行不 ...

  7. Css预处理器实践之Sass、Less大比拼

    xwei | 2012-07-07 | 网页重构 什么是CSS预处理器? Css可以让你做很多事情,但它毕竟是给浏览器认的东西,对开发者来说,Css缺乏很多特性,例如变量.常量以及一些编程语法,代码难 ...

  8. WDCP控制面板安装卸载

    安装 安装源码 WDCP提供两种安装模式,一种是源码安装,一种是RPM包安装,众所周知,源码安装虽然安装时要比RPM包安装繁琐,但是使用上要节省内存.所以我这里主要介绍源码安装. 首先是下载安装源代码 ...

  9. linux磁盘空间用满的处理方法

    linux下空间满可能有两种情况 可以通过命令 df -h  查看磁盘空间占用,实际上是查看磁盘块占用的文件(block) df -i  查看索引节点的占用(Inodes) 磁盘块和索引节点其中之一满 ...

  10. php数组存到文件的实现代码

    php的数组十分强大,有些数据不存入数据库直接写到文件上,用的时候直接require 第一次分享代码: (实际中有用到把数组存在到文件中的功能,不过分享的代码跟实际应用中的有点不同) 代码1: < ...