JVM系列:(五).class文件结构

日期:2019-01-24       浏览:430

各种不同平台的虚拟机与所有平台都统一使用的程序存储格式---字节码(ByteCode)是构成平台无关性的基石。

一 .class文件的来源

计算机只认识0和1,所以我们写的程序需要被编译器翻译成由0和1构成的二进制格式才能被计算机执行。
JVM只认识.class字节码,所以想要在JVM上运行的所有语言都需要编译为JVM能识别的字节码格式。

二 具体结构

2.1 结构

整个 class 文件的结构基本保持了我们编写 java 源码程序的上下结构,其本质上就是一张表,如果所示:
名称 数量 描述
magic 1 魔数
minor_version 1 次版本号
major_version 1 主版本号
constantpoolcount 1 常量池中常量的个数
constant_pool constantpoolcount-1 常量池
access_flags 1 访问标志
this_class 1 类索引
super_class 1 父类索引
interfaces_count 1 接口索引集合容量大小
interfaces interfaces_count
接口索引集合
fields_count 1 字段表集合容量大小
fields fields_count 字段表集合
methods_count 1 方法表集合容量大小
methods methods_count 方法表集合
attributes_count 1 属性表集合容量大小
attributes attributes_count 属性表集合

2.2 描述

  • 魔数:它的唯一作用是用于确定这个文件是否为一个能被虚拟机接受的class文件。使用魔数而不是扩展名来进行识别主要是基于安全考虑,因为文件扩展名可以很随意的被改动。
  • 次版本号:class 文件的版本号。
  • 主版本号:class 文件的版本号,每个JDK大版本的发布,主版本号都会向上加1,高版本的JDK能向下兼容以前版本的class文件,但不能运行以后版本的class文件。
  • 常量池中常量的个数:由于常量池中常量的数量是不固定的,所以在常量池的入口需要设置一个数据表面常量池容量大小。
  • 常量池:常量池主要存放两大类常量,字面量和符合引用。字面量比较接近于Java语言层面的常量概念,如文本字符串、被声明为final的常量值等。而符号引用则包含三类常量(1:类和接口的全限定名、2:字段的名称和描述符、3:方法的名称和描述符)。
  • 访问标志:这个标志用于识别一些类或接口的访问信息,包括:这个class是类还是接口;是否定义为public类型;是否定义为abstract类型;如果是类的话,是否被声明为final等等。
  • 类索引:用于确定这个类的全限定名。
  • 父类索引:用于确定这个类的父类的全限定名。由于Java语言不容许多重继承,所以父类索引只有一个,除了 java.lang.Object 外,所有的Java类都有父类,因此除了 java.lang.Object 外,所有Java类的父类索引都不为0.
  • 接口索引集合容量大小:用于表示接口索引集合的容量大小。
  • 接口索引集合:用来描述这个类实现了哪些接口,这些被实现的接口将按 implements 语句(如果这个类是一个接口,则应当是 extends 语句)后的接口顺序从左到右排列在接口的索引集合中。
  • 字段表集合容量大小:用于表示字段表集合的容量大小
  • 字段表集合:用于描述接口或类中声名的变量,包括了类级变量或实例级变量,但不包括在方法内部声明的变量。包括以下信息:字段的作用域(public、private、protected修饰符)、是类级变量还是实例级变量(static修饰符)、可变性(final)、并发可见性(volatile修饰符,是否强制从主内存读写)、字段名称等。
  • 方法表集合容量大小:用于表示方法表集合的容量大小
  • 方法表集合:用于表示类或接口中定义的方法。和字段表集合类似。
  • 属性表集合容量大小:用于表示属性表集合的容量大小
  • 属性表集合:在class文件、字段表、方法表中都可以携带自己的属性表集合,以用于描述某些场景专有的信息。

三 总结

class文件是Java虚拟机执行引擎的数据入口,也是Java技术体系的基础支柱之一。了解class文件的结构对后面进一步了解虚拟机执行引擎有很重要的意义。

接下来我们将介绍:
  • JVM类加载步骤
扫码关注有惊喜

(转载本站文章请注明作者和出处 qbian)

暂无评论

Copyright 2016 qbian. All Rights Reserved.

文章目录