JVM虚拟机-Class文件之字段表集合

简介: JVM虚拟机-Class文件之字段表集合

 image.gif编辑

 

一、概述

在接口索引集合后面 的就是字段表集合了。字段表(field_info)用于描述接口或者类中声明的变量。字段包括类级变量以及实例级变量,但是不包括在方法内部声明的局部变量。

image.gif编辑

二、字段表集合的构成

1.字段计数器

字段表集合是由很多field_info组成的,所以字段表集合的前两个字节表示有多少个字段,占两个字节,16位。

2.field_info

每个field_info的结构如下表所示:

类型     名称 数量
u2 access_flags 1
u2 name_index 1
u2 descriptor_index 1
u2 attributes_count 1
attribute_info attributes attributes_count

image.gif编辑

3.access_flags

access_flags为字段修饰符,也称字段访问标志。access_flag占2个字节,16位,它与类中的access_flags项目是非常相似的,包括如下类型:

标志名称 标志值 含义
ACC_PUBLIC 0x00 01 字段是否为public
ACC_PRIVATE 0x00 02 字段是否为private
ACC_PROTECTED 0x00 04 字段是否为protected
ACC_STATIC 0x00 08 字段是否为static
ACC_FINAL 0x00 10 字段是否为final
ACC_VOLATILE 0x00 40 字段是否为volatile
ACC_TRANSTENT 0x00 80 字段是否为transient
ACC_SYNCHETIC 0x10 00 字段是否为由编译器自动产生
ACC_ENUM 0x40 00 字段是否为enum

image.gif编辑

某个字段拥有哪些标志符,就是要用访问标识取|操作:

如0x0001|0x0008为0x0009。

4.name_index和descriptor_index

name_index和descriptor_index,是对常量池的引用,name_index指字段的简单名称,descriptor_index指字段描述符。

descriptor_index描述符用来描述字段的数据类型,基本数据类型用一个大写字符来表示,而对象类型则用字符加L加对象名的全限定名来表示。

标志符 含义
B 基本数据类型byte
C 基本数据类型char
D 基本数据类型double
F 基本数据类型float
I 基本数据类型int
J 基本数据类型long
S 基本数据类型short
Z 基本数据类型boolean
V 基本数据类型void
L 对象类型

对数组类型,每一维将使用一个"["字符来描述.如一个Stirng[][]类型的二维数组,将被记录为:[[Ljava/lang/Stirng,一个整型数组"int []"将被记录为"[I"。

三、实例拆解

定义一个类:

public class HelloWord{
    public int i;
    private Long l;
    protected String[][] arrs;
    public Object test(){return null;}
}

image.gif

image.gif编辑

javap -verbose HelloWord.class

public class com.csdn.reader.HelloWord
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #3.#21         // java/lang/Object."<init>":()V
   #2 = Class              #22            // com/csdn/reader/HelloWord
   #3 = Class              #23            // java/lang/Object
   #4 = Utf8               i
   #5 = Utf8               I
   #6 = Utf8               l
   #7 = Utf8               Ljava/lang/Long;
   #8 = Utf8               arrs
   #9 = Utf8               [[Ljava/lang/String;
  #10 = Utf8               <init>
  #11 = Utf8               ()V
  #12 = Utf8               Code
  #13 = Utf8               LineNumberTable
  #14 = Utf8               LocalVariableTable
  #15 = Utf8               this
  #16 = Utf8               Lcom/csdn/reader/HelloWord;
  #17 = Utf8               test
  #18 = Utf8               ()Ljava/lang/Object;
  #19 = Utf8               SourceFile
  #20 = Utf8               HelloWord.java
  #21 = NameAndType        #10:#11        // "<init>":()V
  #22 = Utf8               com/csdn/reader/HelloWord
  #23 = Utf8               java/lang/Object
{
  public int i;
    descriptor: I
    flags: ACC_PUBLIC
  protected java.lang.String[][] arrs;
    descriptor: [[Ljava/lang/String;
    flags: ACC_PROTECTED
  public com.csdn.reader.HelloWord();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return
      LineNumberTable:
        line 3: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       5     0  this   Lcom/csdn/reader/HelloWord;
  public java.lang.Object test();
    descriptor: ()Ljava/lang/Object;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aconst_null
         1: areturn
      LineNumberTable:
        line 8: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0       2     0  this   Lcom/csdn/reader/HelloWord;
}

image.gif

image.gif编辑

四、总结

字段表集合中不会列出从父类或者父接口中继承而来的字段,但有可能列出原来Java代码中不存在的字段和方法,譬如在内部类中为了保持对外部类的访问性,会自动添加指向外部类实例的字段。

另外,在Java语言中字段是无法重载的,两个字段的数据类型,修饰符不管是否相同,都必须使用不一样的名称,但是对于字节码来讲,如果连个字段的描述符不一致,那字段重名就是合法的。

参考资料:

    1. JVM-class文件完全解析-字段表集合 - 小凉 - 博客园
    2. class类文件结构——字段表结构_Joy CR的博客-CSDN博客_字段表是什么
    相关文章
    |
    2月前
    |
    监控 算法 Java
    Java虚拟机(JVM)的垃圾回收机制深度解析####
    本文深入探讨了Java虚拟机(JVM)的垃圾回收机制,旨在揭示其背后的工作原理与优化策略。我们将从垃圾回收的基本概念入手,逐步剖析标记-清除、复制算法、标记-整理等主流垃圾回收算法的原理与实现细节。通过对比不同算法的优缺点及适用场景,为开发者提供优化Java应用性能与内存管理的实践指南。 ####
    |
    1月前
    |
    监控 算法 Java
    Java虚拟机(JVM)垃圾回收机制深度剖析与优化策略####
    本文作为一篇技术性文章,深入探讨了Java虚拟机(JVM)中垃圾回收的工作原理,详细分析了标记-清除、复制算法、标记-压缩及分代收集等主流垃圾回收算法的特点和适用场景。通过实际案例,展示了不同GC(Garbage Collector)算法在应用中的表现差异,并针对大型应用提出了一系列优化策略,包括选择合适的GC算法、调整堆内存大小、并行与并发GC调优等,旨在帮助开发者更好地理解和优化Java应用的性能。 ####
    40 0
    |
    1月前
    |
    存储 监控 算法
    深入探索Java虚拟机(JVM)的内存管理机制
    本文旨在为读者提供对Java虚拟机(JVM)内存管理机制的深入理解。通过详细解析JVM的内存结构、垃圾回收算法以及性能优化策略,本文不仅揭示了Java程序高效运行背后的原理,还为开发者提供了优化应用程序性能的实用技巧。不同于常规摘要仅概述文章大意,本文摘要将简要介绍JVM内存管理的关键点,为读者提供一个清晰的学习路线图。
    |
    1月前
    |
    存储 监控 算法
    Java虚拟机(JVM)垃圾回收机制深度解析与优化策略####
    本文旨在深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法及参数调优方法。通过剖析垃圾回收的生命周期、内存区域划分以及GC日志分析,为开发者提供一套实用的JVM垃圾回收优化指南,助力提升Java应用的性能与稳定性。 ####
    |
    2月前
    |
    机器学习/深度学习 监控 算法
    Java虚拟机(JVM)的垃圾回收机制深度剖析####
    本文深入探讨Java虚拟机(JVM)的垃圾回收机制,揭示其工作原理、常见算法、性能调优策略及未来趋势。通过实例解析,为开发者提供优化Java应用性能的思路与方法。 ####
    54 1
    |
    2月前
    |
    监控 Java 开发者
    Java虚拟机(JVM)深度优化指南####
    本文深入探讨了Java虚拟机(JVM)的工作原理及其性能优化策略,旨在帮助开发者通过理解JVM的内部机制来提升Java应用的运行效率。不同于传统的技术教程,本文采用案例分析与实战技巧相结合的方式,为读者揭示JVM调优的艺术。 ####
    58 8
    |
    3月前
    |
    存储 算法 Java
    Java虚拟机(JVM)的内存管理与性能优化
    本文深入探讨了Java虚拟机(JVM)的内存管理机制,包括堆、栈、方法区等关键区域的功能与作用。通过分析垃圾回收算法和调优策略,旨在帮助开发者理解如何有效提升Java应用的性能。文章采用通俗易懂的语言,结合具体实例,使读者能够轻松掌握复杂的内存管理概念,并应用于实际开发中。
    |
    3月前
    |
    Arthas 监控 数据可视化
    JVM进阶调优系列(7)JVM调优监控必备命令、工具集合|实用干货
    本文介绍了JVM调优监控命令及其应用,包括JDK自带工具如jps、jinfo、jstat、jstack、jmap、jhat等,以及第三方工具如Arthas、GCeasy、MAT、GCViewer等。通过这些工具,可以有效监控和优化JVM性能,解决内存泄漏、线程死锁等问题,提高系统稳定性。文章还提供了详细的命令示例和应用场景,帮助读者更好地理解和使用这些工具。
    |
    2月前
    |
    监控 算法 Java
    深入理解Java虚拟机(JVM)的垃圾回收机制
    【10月更文挑战第21天】 本文将带你深入了解Java虚拟机(JVM)的垃圾回收机制,包括它的工作原理、常见的垃圾收集算法以及如何优化JVM垃圾回收性能。通过本文,你将对JVM垃圾回收有一个全新的认识,并学会如何在实际开发中进行有效的调优。
    60 0
    |
    3月前
    |
    SQL 缓存 Java
    JVM知识体系学习三:class文件初始化过程、硬件层数据一致性(硬件层)、缓存行、指令乱序执行问题、如何保证不乱序(volatile等)
    这篇文章详细介绍了JVM中类文件的初始化过程、硬件层面的数据一致性问题、缓存行和伪共享、指令乱序执行问题,以及如何通过`volatile`关键字和`synchronized`关键字来保证数据的有序性和可见性。
    38 3