Java 类文件结构
Java 诞生之时有句著名的宣传口号“Write Once, Run Anywhere.”。但是,Java 语言本身不具备跨平台的能力,而是 JVM 提供了跨平台的能力。
事实上,不仅 Java 可以运行在 JVM 上,现在已经出现了其他的语言可以运行在 JVM 上,如 Clojure、Scala 等。也就是说,JVM 并不和包括 Java 在内的任何语言绑定,只与“Class 文件”这种特定的二进制文件格式相关联,Class 文件包含了 Java 虚拟机指令集和符号表以及若干其他辅助信息。这篇文章就主要介绍存储字节码的 Class 文件。
任何一个 Class 文件都对应着唯一一个类或接口的定义信息,但是,类或接口的定义信息并非一定要在类文件中。
Class 文件是一组以 8 位为基础单位的字节流(二进制流),每个数据项严格按照顺序节凑排列在 Class 文件中,中间没有任何分隔符。多字节的数据项按照大端序存储(高字节存储在最低地址位)。
基本概念
JVM 规范规定,Class 文件采用一种类似于 C 语言结构体的伪结构来存储数据,这种伪结构中只有两种数据类型:无符号数和表。
- 无符号数是基本的数据类型,以 u1、u2、u3、u4 分别代表 1 个字节、2 个字节、3 个字节、 4 个字节。无符号数可以用来描述数字、索引引用、数量值或者按照 UTF-8 编码构成字符串值。
- 表由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表都习惯地以"_info"结尾。表用于描述有层次关系的复合结构的数据,这个 Class 文件本质上就是一张表。
文件结构
ClassFile {
u4 magic;
u2 minor_version;
u2 major_version;
u2 constant_pool_count;
cp_info constant_pool[constant_pool_count-1];
u2 access_flags;
u2 this_class;
u2 super_class;
u2 interfaces_count;
u2 interfaces[interfaces_count];
u2 fields_count;
field_info fields[fields_count];
u2 methods_count;
method_info methods[methods_count];
u2 attributes_count;
attribute_info attributes[attributes_count];
}
每个 Class 文件就对应这样一个 ClassFile 的结构。
无论是无符号数还是表,当需要描述同一类型但数量不定的多个数据时,经常会使用一个前置的容量计数器加若干个连续的数据项的形式,这是称这一序列连续的某一个类型的数据为某一类型集合。如 fields_count
来描述 field_info
的数量(这些 field_info
就构成一个集合)。
ClassFile 中每个项目解释如下表(attributes_count 和 attributes[] 比较复杂,这里暂不介绍,我会在文章末尾提供参考资料):
item | 含义 |
---|---|
magic | 魔数,它的唯一作用时确定这个文件能否为一个能被虚拟机接受的 Class 文件。许多文件标准中都使用魔数来进行身份标识。Class 文件的魔数值为:0xCAFEBABE |
minor_version | 这个类文件的次版本号。 |
major_version | 这个类文件的主版本号。 |
constant_pool_count | 常量池容器计数值,等于常量池(constant_pool) 中实体数量加 1 。常量池的索引只有在比零大,比该值小才认为是有效的。 |
constant_pool[] | 常量池中的结构表示字符串常量、类名字、接口名字、字段(field name)、其他常量(指向 ClassFile 中的其他结构、子结构)。 |
access_flag | 访问标志。用于识别一些类或接口层次的访问信息,包括:这个 Class 是类还是接口;是否定义为 public;是否定义为 abstract 类型;如果是类的话,是否被声明为 final 等。 |
this_class | 用于确定这个类的全限定名。 |
super_class | 用于确定这个类的父类的全限定名。 |
interfaces_count | 用于标识类实现了几个接口。 |
interfaces[] | 类实现了哪些接口,按 implements 后的顺序显示在这个集合中。 |
fields_count | 用于描述接口或者类中声明的变量的数量,字段包括类级变量以及实例级变量。 |
fields[] | 用于描述接口或者类中声明的变量,字段包括类级变量以及实例级变量。描述信息包括:字段的作用域(public、private、protected)、实例变量还是类变量(static)、可变性(final)、并发可见性(volatile)、字段数据类型、字段名称、可否被序列化。除字段数据类型、字段名称需要引用常量池中常量来描述外,其余均用标志位来表示。 |
methods_count | 接口或类中方法的数量。 |
methods[] | 描述接口或类中的方法。 |
Class 的文件格式大体上就是这样,还有大量细节没有描述,如常量池中各种常量项的结构、访问标志具体值与名称、字段描述符、方法描述符、属性表等。由于这些都是规范,这里不再写了,想更近一步了解的话,可以阅读 Java 虚拟机规范。
参考:
The Java Virtual Machine Specification, Java SE 8 Edition
《深入理解Java虚拟机》
Java 类文件结构的更多相关文章
- 《深入理解java虚拟机》笔记——简析java类文件结构
一直不太搞得明确jvm究竟是如何进行类载入的,在看资料的过程中迷迷糊糊.在理解类载入之前,首先看看java的类文件结构究竟是如何的,都包含了哪些内容. 最直接的參考当然是官方文档:The Java® ...
- 不知道Java类文件结构的同学,看这篇文章就够了
一.前言 代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步.经过多年的发展,目前的计算机仍然只能识别0和1,但是由于近10年内虚拟机以及大量建立在虚拟机之上的程 ...
- Java类文件结构详解
概述: Class文件结构是了解虚拟机的重要基础之一,如果想深入的了解虚拟机,Class文件结构是不能不了解的.Class文件是一组以8位字节为基础单位的二进制流,各项数据项目严格按照顺序紧凑地排列在 ...
- java类文件结构笔记
注:新的博客地址 - https://zhengw-tech.com/archives/ 我们都知道java实现跨平台靠的是虚拟机技术,将源文件编译成与操作系统无关的,只有虚拟机能识别并执行的字节码文 ...
- Java类文件结构
一.概述 实现语言无关性的基础是虚拟机和字节码存储格式.Java虚拟机不和包括Java在内的任何语言绑定,只与"Class文件"这种特定的二进制文件所关联,Class文件中包含了J ...
- Java类文件结构及javac的ClassReader类解读
首先来看一下ClassFile,类注释如下: A JVM class file. Generic Java classfiles have one additional attribute for c ...
- Java虚拟机,类文件结构深度解析
Java类文件结构 Java虚拟机不和包括Java在内的任何语言绑定,只与 "Class文件" 这种特定的二进制文件所关联, Class文件中包含了Java虚拟机指令集合符号表以及 ...
- JVM学习笔记(三):类文件结构
代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 实现语言无关性的基础是虚拟机和字节码存储格式.Java虚拟机不和包括Java在内的任何语言绑定,只与&quo ...
- JVM类文件结构
作为一名Java后台开发的程序员, 深入理解JVM, 重要性不言而喻, 这篇文章主要是记录JVM类文件结构相关知识. 2. 实例 这部分比较抽象, 所以以实例的形式来学习. 这部分作为资料, 以便后面 ...
随机推荐
- Python接口测试,Requests模块讲解:GET、POST、Cookies、Session等
文章最下方有对应课程的视频链接哦^_^ 一.安装.GET,公共方法 二.POST 三.Cookies 四.Session 五.认证 六.超时配置.代理.事件钩子 七.错误异常
- java 集合框架(一)概述
一.概述 Java Collection Framework (JCF) 提供给我们一系列的类和接口,方便开发者处理集合对象. 在Java 2之前,Java是没有完整的集合框架的.它只有一些简单的可以 ...
- a链接在新窗口打开
平时用的收集了几种方法 1.在head标签里添加,base最大的用处就是可以改变某一个网页默认的属性 <base target="_blank"/> 2.Jquery ...
- MinGW下简单编译FFmpeg
2009.03.21补充:ffmpeg-0.5正式发布,地址为:[url]http://www.ffmpeg.org/releases/ffmpeg-0.5.tar.bz2[/url].修改了第7步, ...
- FusionCharts MSBar2D图
1.页面展示 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> ...
- 【linux】mysql安装问题 g++: not found
问题现象: ../depcomp: line 512: exec: g++: not foundmake[2]: *** [my_new.o] Error 127make[2]: Leaving di ...
- hi3531调用sil9024的驱动
//测试mao printf("\n\n"); unsigned int cmd=1; unsigned long arg =4; fd = open(" ...
- SQL语句异常导致项目报错
1.错误描述 严重:Exception occurred during processing request:Statement Callback;SQL[ ];OALL8处于不一致状态; nes ...
- Linux查看当前正在运行的进程
Linux查看当前正在运行的进程 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ ps PID TTY TIME CMD 2576 pts/0 00:00:00 ...
- Java和Flex整合报错(三)
1.错误描述 信息: Initializing Spring FrameworkServlet 'mvc' 11-13 23:43:42 INFO [localhost-startStop-1] or ...