java类文件结构笔记
注:新的博客地址 - 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类文件结构笔记的更多相关文章
- 《深入理解java虚拟机》笔记——简析java类文件结构
一直不太搞得明确jvm究竟是如何进行类载入的,在看资料的过程中迷迷糊糊.在理解类载入之前,首先看看java的类文件结构究竟是如何的,都包含了哪些内容. 最直接的參考当然是官方文档:The Java® ...
- 不知道Java类文件结构的同学,看这篇文章就够了
一.前言 代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步.经过多年的发展,目前的计算机仍然只能识别0和1,但是由于近10年内虚拟机以及大量建立在虚拟机之上的程 ...
- Java 类文件结构
Java 诞生之时有句著名的宣传口号"Write Once, Run Anywhere.".但是,Java 语言本身不具备跨平台的能力,而是 JVM 提供了跨平台的能力. 事实上, ...
- Java类文件结构详解
概述: Class文件结构是了解虚拟机的重要基础之一,如果想深入的了解虚拟机,Class文件结构是不能不了解的.Class文件是一组以8位字节为基础单位的二进制流,各项数据项目严格按照顺序紧凑地排列在 ...
- Java类文件结构
一.概述 实现语言无关性的基础是虚拟机和字节码存储格式.Java虚拟机不和包括Java在内的任何语言绑定,只与"Class文件"这种特定的二进制文件所关联,Class文件中包含了J ...
- Java类文件结构及javac的ClassReader类解读
首先来看一下ClassFile,类注释如下: A JVM class file. Generic Java classfiles have one additional attribute for c ...
- JVM学习笔记(三):类文件结构
代码编译的结果从本地机器码转变为字节码,是存储格式发展的一小步,却是编程语言发展的一大步. 实现语言无关性的基础是虚拟机和字节码存储格式.Java虚拟机不和包括Java在内的任何语言绑定,只与&quo ...
- Java虚拟机,类文件结构深度解析
Java类文件结构 Java虚拟机不和包括Java在内的任何语言绑定,只与 "Class文件" 这种特定的二进制文件所关联, Class文件中包含了Java虚拟机指令集合符号表以及 ...
- JVM类文件结构
作为一名Java后台开发的程序员, 深入理解JVM, 重要性不言而喻, 这篇文章主要是记录JVM类文件结构相关知识. 2. 实例 这部分比较抽象, 所以以实例的形式来学习. 这部分作为资料, 以便后面 ...
随机推荐
- 爬虫之BeautifulSoup类
安装:pip install BeautifulSoup4 下表列出了主要的解析器,以及它们的优缺点:看个人习惯选取自己喜欢的解析方式 # 获取html代码 import requests r = r ...
- TCP/IP协议基本知识
1.TCP/IP协议中主机与主机之间通信的三要素: IP地址(IP address) 子网掩码(subnet mask) IP路由(IP router) 2.IP地址的分类及每一类的范围: A类1-1 ...
- 干货来啦。Flask框架看这一篇就够了,关注不迷路,Jeff带你看源码。开发技术时时更新
目录 一.初识Flask 1.1 什么是flask? 1.2 为什么要有flask? 二.Flask快速启动 三.Flask四剑客 三.flask的配置文件 可以配置的属性 四.flask路由 4.1 ...
- nlogn的最长不下降子序列【tyvj1254挑选士兵】
var a,d:Array[-..]of longint; i,n,m,k,l:longint; function erfen(x:longint):longint; var mid,h,t:long ...
- Flask 偏函数、g对象、flask-session、数据库连接池、信号、自制命令、flask-admin
目录 一.偏函数 二.g对象 g对象和session的区别 三.flask-session 四.数据库连接池 pymsql链接数据库 数据库连接池版 utils/sql.py 五.信号 六.命令fla ...
- Java-字节输入输出。(新手)
参考手册: BufferedInputStream BufferedOutputStream 实例: import java.io.*; /* * 文件的复制方式 * 1 字节流读写单个字节 * 2 ...
- 性能测试工具LoadRuner你所不知道的内幕
谈到性能测试,大家一定会联想到Jmeter和LoadRunner,这两款工具目前在国内使用的相当广泛,主要原因是Jmeter是开源免费,LoadRunner 11在现网中存在破解版本.商用型性能测试工 ...
- Spring Cloud 系列之 Netflix Hystrix 服务监控
Actuator Hystrix 除了可以实现服务容错之外,还提供了近乎实时的监控功能,将服务执行结果和运行指标,请求数量成功数量等等这些状态通过 Actuator 进行收集,然后访问 /actuat ...
- Cobait Strike的socks与ew代理使用
cobait strike介绍 Cobalt Strike 一款以 metasploit 为基础的 GUI 的框架式渗透测试工具,集成了端口转发.服务扫描,自动化溢出,多模式端口监听,win exe ...
- Java并发编程(03):多线程并发访问,同步控制
本文源码:GitHub·点这里 || GitEE·点这里 一.并发问题 多线程学习的时候,要面对的第一个复杂问题就是,并发模式下变量的访问,如果不理清楚内在流程和原因,经常会出现这样一个问题:线程处理 ...