注:新的博客地址 - 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. Redis(7)——持久化【一文了解】

    一.持久化简介 Redis 的数据 全部存储 在 内存 中,如果 突然宕机,数据就会全部丢失,因此必须有一套机制来保证 Redis 的数据不会因为故障而丢失,这种机制就是 Redis 的 持久化机制, ...

  2. aosp Pixel 修改 SIM 卡支持及解决网络带x问题

    去除网络X的方法 adb shell settings put global captive_portal_https_url http://g.cn/generate_204 自己用 php 做一个 ...

  3. 阿里AI芯片:12nm工艺、709平方毫米大核心

    含光出自<列子·汤问>篇有“上古三剑”一章,寓意含而不露,光而不耀,象征含光 800 无形却强劲的算力. 含光 800 是一款 AI 芯片,偏重推理.据介绍,1 颗含光 800 的算力相当 ...

  4. Java反射之成员变量的反射

    上一篇介绍了Java反射之构造方法反射.这次我们在说一说如何反射类中的成员变量并用作一个简单案例. [一]Field类 Filed类代表字段,包含字段拥有的所有属性,比如修饰符,变量类型,值等等,Fi ...

  5. LeetCode#15 | Three Sum 三数之和

    一.题目 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有满足条件且不重复的三元组. 注意:答案中不可以包含 ...

  6. h5微信中视频禁止全屏

    <video id="videoPlayer" v-show="isShowVideo" class="video" ref=&quo ...

  7. vue的$message(提示框换行)

    之前一直在搜怎么让提示框的文字换行,网上搜到的基本都是使用 ‘ /n ’,使用无效,也试了css换行,本来想用弹窗自己编辑html内容,还好回去官网看了一下: let arr = ['测试一', '测 ...

  8. Pyinstaller通过spec文件打包py程序(多个py脚本)

    Pyinstaller pyinstaller是python的一个第三方模块,使用它可以将python程序打包为可执行文件,实现打包后的程序在没有python环境的机器上也可以运行.pyinstall ...

  9. 图解I/O模型

      本文带你鸟瞰I/O模型全貌,希望可以让你对I/O模型有一个直观的认识 什么是I/O?I/O的过程?同步阻塞 I/O同步非阻塞 I/OI/O多路复用异步I/O 什么是I/O?   I/O就是计算机内 ...

  10. hdu3294 Manacher算法模板

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/3294/ 回文长度如果是mxx,回文中心是id的话,在扩展串中(id-mxx+1,id+mxx-1)的这段中去除标 ...