Jvm(38),class文件结构----字段表集合

0.前言

读完本文,你将会学到:

1、类中定义的field字段是如何在class文件中组织的 2、不同的数据类型在class文件中是如何表示的 3、static final类型的field字段的初始化赋值问题

1.概述

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

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

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

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

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

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

下面我将一一讲解FIeld_info的组成元素:访问标志(access_flags)、名称索引

(name_index)、描述索引(descriptor_index)、属性表集合

  1. field字段的访问标志

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

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

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

ACC_STATIC组成。

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

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

ACC_STATIC。

5. 字段的数据类型表示和字段名称表示 class文件对数据类型的表示如下图所示:

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

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

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

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

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

对于虚拟机而言,上述的两个field字段赋值的时机是不同的: 对于非静态(即无static修饰)的field字段的赋值将会出现在实例构造方法

()中

对于静态的field字段,有两个选择:1、在静态构造方法()中进行;2 、使用ConstantValue属性进行赋值

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

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

String类型,那么将在类构造方法()中赋值。

对于上述的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;

  1. 名称索引中的值为0x0005,指向了常量池中的第5项,为"str",表明这个field 字段的名称是str;
  2. 描 述 索 引 中 的 值 为 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赋值。

原文地址:https://www.cnblogs.com/qingruihappy/p/9691426.html

时间: 2024-08-01 11:31:44

Jvm(38),class文件结构----字段表集合的相关文章

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

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

JVM-class文件完全解析-字段表集合

 字段表集合 这个class文件的解析,分析得有点太久了.前面介绍类魔数,次版本号,主板本号,常量池入口,常量池,访问标志,类索引,父类索引和接口索引集合.下面就应该到字段表集合了.  紧接着接口索引集合的就是字段表的集合了. 字段表(field_info)用于描述接口或者类中声明的变量.字段包括类级变量以及实例级变量,但是不包括在方法内部声明的局部变量. 字段表的结构: 类型 名称 数量 u2 access_flags 1 u2 name_index 1 u2 descriptor_index

深入理解Java虚拟机笔记---字段表集合

字段表(field_info)用于描述接口或类中声明的变量.字段(field)包括了类级变量或实例变量,但不包括方法内部声明的变量.描述一个字段的信息有:字段的作用域(public,private,protected修饰符),是类级变量还是实例级变量(static修饰符),可变性(final),并发可见性(volatile修饰符,是否强制从主内存读写),是否可序列化(transient修饰符),字段数据类型(基本数据类型,对象,数组),字段名称.这些信息中,各个修改符都是布尔值,要么有某个修饰符

Jvm(39),class文件结构----- 方法表集合

类中定义的method方法是如何在class文件中组织的 method方法的表示-方法表集合在class文件的什么位置 类中的method方法的实现代码---即机器码指令存放到哪了,并初步了解机器指令 为什么没有在类中定义自己的构造函数,却可以使用new ClassName()构造函数创建对象 IDE代码提示功能的基本原理 1.概述 方法表集合是指由若干个方法表(method_info)组成的集合.对于在类中定义的若干个,经过JVM编译成class文件后,会将相应的method方法信息组织到一个

深入理解JVM(七)——Class文件结构

什么是JVM的"无关性"? Java具有平台无关性,也就是任何操作系统都能运行Java代码.之所以能实现这一点,是因为Java运行在虚拟机之上,不同的操作系统都拥有各自的Java虚拟机,因此Java能实现"一次编写,处处运行". 而JVM不仅具有平台无关性,还具有语言无关性. 平台无关性是指不同操作系统都有各自的JVM,而语言无关性是指Java虚拟机能运行除Java以外的代码! 这听起来非常惊人,但JVM对能运行的语言是有严格要求的.首先来了解下Java代码的运行过

JVM初探之类文件结构

java 的 .class 文件字节码如图:Class 文件是一组以8字节为基础单位的二进制流,各个数据项目有着严格的结构.下面我们介绍下class文件的结构. 魔数 class文件的头4个字节是魔数:  ,他的作用便是验证这个文件是否是一个java虚拟机可以使用的文件, 版本号 接下来的是两个字节的小版本号,和两个字节的大版本号:  . 常量池结构 它分为两个部分: 第一部分是:常量池的容量:  即二进制 54 ,代表了 53 项常量,注意这里的容量计数是从 1 开始的即索引范围是 1 ~ 5

JVM小结--类文件结构

字节码是构成Java平台无关性的基石.实现语言无关性的基础是虚拟机和字节码存储格式. Java语言中的各种变量.关键字和运算符的语义最终是由多条字节码命令组成,因此字节码命令所能提供的语义描述能力肯定会比Java语言本身更强大. Class类文件的结构 Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在Class文件中,中间没有添加任何分隔符,所以整个Class文件中存储的内容基本上程序运行中必要的数据. 当遇到需要占用8位字节以上空间的数据项时,则会按照高

JVM 之 Class文件结构

JVM 之 Class文件结构 本文写作目的: 1)为了加深自己学习的理解,2)帮助正在学习研究JVM的同仁,3)与任何热爱技术的达人交流经验,提升自己 以此为本,文章会尽量写的简洁,尽量保证理解的正确性,如有任何理解不到位或错误的地方,希望朋友们及时指出,严厉拍砖. 开始之前我们需要先了解一些基本的概念,这些概念是学习整个JVM原理的基础. 1)JVM虚拟机规范主要规范了Class文件结构,虚拟机内存结构,虚拟机加载,解析,执行Class文件的行为方式,以及一系列的字节码指令集. 2)Clas

JVM之Class文件结构

每一个class文件对应一个类或者接口,但是一个类或者接口不一定生成class文件,classloader直接生成. 8为字节为基础的二进制流,各个数据项按照严格的顺序排列在class文件中,没有任何分隔符,当遇到需要占用8位字节以上的数据项时,则会按照高位在前(或低位在前)方式分割为若干个8位字节存储.Big-Endian Little-Endian. 类似C语言结构体的微结构来存储数据,只包含无符号数和表两种结构. 无符号数:u1,u2,u3,u4代表响应字节大小的无符号数,用来描述数字,索