注:新的博客地址 - https://zhengw-tech.com/archives/

我们都知道java实现跨平台靠的是虚拟机技术,将源文件编译成与操作系统无关的,只有虚拟机能识别并执行的字节码文件,由各个操作系统上的jvm来负责执行,屏蔽了底层具体的操作系统。这里我们就来认识一下这个只有jvm才认识的字节码文件的真实样子。

为了节省空间,类文件中没有任何分隔符,各个数据项都是一个挨着一个紧凑排列的,所以其中无论是顺序还是数量等都是严格规定的,哪个字节代表什么含义,长度是多少,先后顺序如何,都不允许改变。下面我们先看一下类文件的整体结构:

Class文件结构

其中常量、接口、字段、方法和属性在其中按各自的结构紧密排列,个数由其前面的数量字段决定。同时类文件中最小单位为1个字节,超过一个字节的数据以大端方式存储。

下面依次介绍其中的每个部分:

魔数

魔数是用来确定文件的类型是否是class文件,因为只靠文件扩展名来确定文件类型并不可靠。

这个魔数占文件的开始4个字节,为CA FE BA BE。(注意:这里的字面代表的是十六进制数,而不是ASCII码)

版本号

接下来的4个字节为class文件版本号,其中前两个字节表示的是次版本号,后两个字节表示的是主版本号(从45开始)。

虚拟机可以向下兼容运行class文件,但不能运行高于其版本的class文件。

常量池

由于常量池中的常量数量是不确定的,所以在常量池的入口需要有两个字节用来代表常量池容量计数值(常量池索引从1开始)。

一共有14种常量类型,有着各自对应的结构,但开始的一个字节同样都是表示标志位,用来区分不同的类型。

下面为14种常量的具体类型和对应的标志位:

每种类型的结构如下(其中u1表示1个字节,u2表示2个字节,其他同理):

读取常量池的时候首先读取标志位,判断常量类型,就可以知道对应的结构,获取对应的信息了。

访问标志

常量池之后的两个字节代表访问标志,即这个class是类还是接口,是否为public等的信息。不同的含义有不同的标志值(没有用到的标志位一律为0。),具体信息如下:

类索引

类索引占两个字节,分别指向常量池中的CONSTANT_Class_info类型的常量,这个类型的常量结构见常量池中的图表,其中包含一个指向全限定名常量项的索引。

父类索引

因为java只允许单继承,所以只有一个父类,具体内容同上-类索引。

接口索引

接口索引开始两个字节用来表示接口的数量,之后的每两个字节表示一个接口索引,用法同类索引与父类索引。

字段

字段用于描述接口或者类中声明的变量,包括类级变量以及实例变量,但不包括局部变量。

字段域的开始两个字节表示字段数量,之后为紧密排列的字段结构体数据,其结构如下:

其中的字段和方法的描述符,对于字段来说用来描述字段的数据类型;而对于方法来说,描述的就是方法的参数列表(包括数量、类型以及顺序)和返回值,这个描述顺序也是固定的,必须是参数列表在前,返回值在后,参数列表必须放在一组小括号内。同时为了节省空间,各种数据类型都使用规定的一个字母来表示,具体如下:

对象使用L加上对象的全限定名来表示,而数组则是在每一个维度前添加一个"["来描述。

属性表在之后进行介绍。

方法

class文件中对方法的描述与以前对字段的描述几乎采用了完全一致的方式,唯一的区别就是访问类型不完全一致。

属性

java7中预定义了21项属性,具体内容限于篇幅不再列出。

对于每个属性的结构,没有特别严格的要求,并且可以自定义属性信息,jvm运行时会忽略不认识的属性。

符合规范的属性表基本结构如下:

其中前两个字节为指向常量池中的CONSTANT_Utf8_info类型的属性名称,之后4个字节表示属性值所占用的位数,最后就是具体属性了。

其中有一个比较重要的名称为「Code」的属性为方法的代码,即字节码指令。

Code属性表结构如下:

以上只列出了一些Class文件最基本的结构,如有错误欢迎指正。

另:目前准备写一个基于字节码,分析方法(类、包)间的调用关系工具,项目地址:https://github.com/zavier/jclass-relation ,欢迎有兴趣的同学PR

java类文件结构笔记的更多相关文章

  1. 《深入理解java虚拟机》笔记——简析java类文件结构

    一直不太搞得明确jvm究竟是如何进行类载入的,在看资料的过程中迷迷糊糊.在理解类载入之前,首先看看java的类文件结构究竟是如何的,都包含了哪些内容. 最直接的參考当然是官方文档:The Java® ...

  2. 不知道Java类文件结构的同学,看这篇文章就够了

    一.前言 代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步.经过多年的发展,目前的计算机仍然只能识别0和1,但是由于近10年内虚拟机以及大量建立在虚拟机之上的程 ...

  3. Java 类文件结构

    Java 诞生之时有句著名的宣传口号"Write Once, Run Anywhere.".但是,Java 语言本身不具备跨平台的能力,而是 JVM 提供了跨平台的能力. 事实上, ...

  4. Java类文件结构详解

    概述: Class文件结构是了解虚拟机的重要基础之一,如果想深入的了解虚拟机,Class文件结构是不能不了解的.Class文件是一组以8位字节为基础单位的二进制流,各项数据项目严格按照顺序紧凑地排列在 ...

  5. Java类文件结构

    一.概述 实现语言无关性的基础是虚拟机和字节码存储格式.Java虚拟机不和包括Java在内的任何语言绑定,只与"Class文件"这种特定的二进制文件所关联,Class文件中包含了J ...

  6. Java类文件结构及javac的ClassReader类解读

    首先来看一下ClassFile,类注释如下: A JVM class file. Generic Java classfiles have one additional attribute for c ...

  7. JVM学习笔记(三):类文件结构

    代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 实现语言无关性的基础是虚拟机和字节码存储格式.Java虚拟机不和包括Java在内的任何语言绑定,只与&quo ...

  8. Java虚拟机,类文件结构深度解析

    Java类文件结构 Java虚拟机不和包括Java在内的任何语言绑定,只与 "Class文件" 这种特定的二进制文件所关联, Class文件中包含了Java虚拟机指令集合符号表以及 ...

  9. JVM类文件结构

    作为一名Java后台开发的程序员, 深入理解JVM, 重要性不言而喻, 这篇文章主要是记录JVM类文件结构相关知识. 2. 实例 这部分比较抽象, 所以以实例的形式来学习. 这部分作为资料, 以便后面 ...

随机推荐

  1. python初学者必看学习路线图!!!

    python应该是近几年比较火的语言之一,很多人刚学python不知道该如何学习,尤其是没有编程基础想要从事程序员工作的小白,想必应该都会有此疑惑,包括我刚学python的时候也是通过从网上查找相关资 ...

  2. linux4.1.36 解决 SPI 时钟找不到 不生成设备 device

    最初的问题是 编译内核添加了 spi 支持,配置了 board 后,加载25q64驱动不执行probe 函数. 然后发现是,spi-s3c24xx.c 中的 probe 没有执行完就退出了 没有生成 ...

  3. golang的sync.WaitGroup使用示例

    下面一段代码 len(m) 不一定会打印为 10,为什么?.如果想要 len(m) 打印为 10,应该怎么修改代码? func main() { const N = 10 m := make(map[ ...

  4. Tries前缀树

    Trie,来源于(retrieval,取回,数据检索),是一种多叉树,用来存储字母表上的单词非常有用. Trie经常用来存储动态集合(dynamic set)或者关联数组(associative ar ...

  5. ML-Agents(二)创建一个学习环境

    ML-Agents(二)创建一个学习环境 一.前言 上一节我们讲了如何配置ML-Agents环境,这一节我们创建一个示例,主要利用Reinforcement Learning(强化学习). 如上图,本 ...

  6. 一文了解服务端推送(含JS代码示例)

    常用的服务端推送技术,包括轮询.长轮询.websocket.server-sent-event(SSE) 传统的HTTP请求是由客户端发送一个request,服务端返回对应response,所以当服务 ...

  7. [Alg] 文本匹配-单模匹配与多模匹配

    实际场景: 网站的用户发了一些帖子S1, S2,...,网站就要审核一下这些帖子里有没有敏感词. 1. 如果网站想查一下帖子里有没有一个敏感词P,这个文本匹配要怎么做更快? 2. 如果网站想查一下帖子 ...

  8. Redis入门学习(学习过程记录)

    Redis(入门笔记) 学习一个大的技术点,然后顺带着就把这个技术点的面试题给学习了. 学习完一个技术后,如果面试题还不能够解答的话,只能说明学的不精,需要查漏补缺. 下一个学习的方向:Redis-非 ...

  9. Natas34 Writeup(闯关结束!)

    Natas34: 登录什么都不用做,闯关结束!撒花~~~

  10. Android 引导页的代码

    布局代码 <android.support.v4.view.ViewPager android:id="@+id/viewpage" android:layout_width ...