Class类文件的结构

Class文件是一株以8个字节为单位的二进制流。各个数据项目严格按照顺序紧凑的排列在文件之中,中间没有任何的分隔符,当遇到占用的空间大于8个字节时,会按照高位在前的方式进行分割,分割单位还是8个字节。

Class文件格式采用一种类似于C语言结构体的伪结构体来存储数据,这种伪结构中只有两种数据类型:无符号数和表

  • 无符号数:属于基本的数据类型,以u1,u2,u4,u8分别代表1个字节,2个字节,4个字节,8个字节的无符号数,他可以用来描述索引,数字,数量值或者按照utf8彪马构成字符串值。
  • 表:属于复合数据类型,是由多个基础类型或者表组合而成。为了区分表和基础数据类型,通常表的命名都是以“_info”结尾的。表示描述的是具有层次关系的数据。整个Class文件本质上也可以看做是一张表。
ClassFile {
u4 magic; //Class 文件的标志
u2 minor_version;//Class 的小版本号
u2 major_version;//Class 的大版本号
u2 constant_pool_count;//常量池的数量
cp_info constant_pool[constant_pool_count-1];//常量池
u2 access_flags;//Class 的访问标记
u2 this_class;//当前类
u2 super_class;//父类
u2 interfaces_count;//接口
u2 interfaces[interfaces_count];//一个类可以实现多个接口
u2 fields_count;//Class 文件的字段属性
field_info fields[fields_count];//一个类会可以有个字段
u2 methods_count;//Class 文件的方法数量
method_info methods[methods_count];//一个类可以有个多个方法
u2 attributes_count;//此类的属性表中的属性数
attribute_info attributes[attributes_count];//属性表集合
}

魔数与Class文件的版本

魔数:每个Class文件的前四个直接被称为魔数。

作用:确定这个文件是否是一个被虚拟机接收的Class文件。

为什么不是用文件的扩展名来进行虚拟机的识别标志?

因为文件的扩展名可以被用户随意更改。但是魔数是嵌入在文件头的,不会改变。

Class文件的版本号:紧跟魔数后边的四个字节,这四个字节中前两个字节是次版本号,后两个是主版本号。高版本可以兼容低版本的Class文件。

注意:可以使用WinHex软件打开Class文件,查看分析字节对应的内容。

常量池

常量池:紧接着主次版本号,u2,两个字节表示常量池的数量,从1开始计算,原因是将第0项空出来表示不引用常量池中任何项目。是与其他项目关联最多的数据类型,也是Class文件空间中最大的项目。

常量池主要存放两种常量:字符量和符号引用。

字符量:如字符串,声明时final类型的变量等。

符号引用:属于编译原理上的概念,包括三种,类和接口的全限定名,字段的名称和描述符,方法的名称和描述符。

常量池中的每一项都是一个表,17种表中,表开始的第一位是一个u1类型的标志位,代表当前这个常量属于哪种常量类型。

Java程序中如果定义了超过64kb英文的字符的变量或方法名,将会无法编译。

javap:一个专门用于分析Class文件的字节码工具,可以通过-verbose参数输出的.class文件内容。

访问标志

在常量池结束之后,紧接着的两个字节代表访问标志,这个标志用于识别一些类或者接口层次的访问信息,包括这个Class是类还是接口,访问权限是public还是private,是否是abstract,是否被final修饰等。

类索引与接口索引集合

类索引和父类索引都是u2类型的数据,而接口索引是一组u2类型的集合,Class文件通过这三种数据来确定类的继承关系。

类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名。

接口索引就是用来描述这个类实现了哪几种接口。集合中的顺序是按照implements后面的接口顺序。

类索引,父类索引,接口索引都是按照顺序排列在访问标志之后。

类索引和父类索引的索引值指向了一个类型是CONSTANT_Class_info的类描述符常量。这个常量的值又指向了CONSTANT_Utf8_info类型的全限定名 字符串。(全限定名例如:org/fenixsoft/clazz/TestClass;其实就是将 “.” 换成“/”)

对于接口索引集合,入口的第一项u2类型的数据为接口计数器(interfaces_count),表示索引表
的容量。如果该类没有实现任何接口,则该计数器值为0,后面接口的索引表不再占用任何字节。

字段集合

字段表:用于描述接口或者类中声明的变量。Java中的字段不包括方法内部的局部变量。

字段表结构

access_flag:字段的作用域

name_inedx:对常量池的引用,表示字段名称。

descriptor_index:对常量池的引用,表示字段和方法的描述符,用来描述字段的数据类型,方法的参数列表和返回值。

attribute_count:表示额外属性字段。

attributes:表示具体属性。

方法集合

方法表结构和字段表结构差不多,依次是访问标志,名称索引,描述符索引,属性表集合

方法访问标志

Java方法中的具体代码在属性表集合中的一个叫做Code的属性里面。

与字段表集合相对应地,如果父类方法在子类中没有被重写(Override),方法表集合中就不会出
现来自父类的方法信息。

重载方法为什么不能依靠返回值来判断?

特征签名:指一个方法中各个参数在常量池中的字段符号引用的集合。

也正是因为返回值不会包含在特征签名之中,所以Java语言里面是无法仅仅依靠返回值的不同来对一个已有方法进行重载的。

属性表集合

字段表、方法表都可以携带自己的属性集合,用来描述某种场景的专有信息。

属性表集合对属性的顺序没有要求,只是不允许有重复的属性名。

集合中的每一个属性,它的名称都要从常量池中引用一个CONSTANT_Utf8_info类型的常量来表示,而属性值的结构是自定义的。

属性列表

JVM-Class文件的结构的更多相关文章

  1. JVM(五) class类文件的结构

    概述 class类文件的结构可见下面这样图(出处见参考资料),可以参照下面的例子,对应十六进制码,找出找出相应的信息. 其中u2 , u4 表示的意思是占用两个字节和占用四个字节,下面我们将会各项说明 ...

  2. 类文件的结构、JVM 的类加载过程、类加载机制、类加载器、双亲委派模型

    一.类文件的结构 我们都知道,各种不同平台的虚拟机,都支持 "字节码 Byte Code" 这种程序存储格式,这构成了 Java 平台无关性的基石.甚至现在平台无关性也开始演变出 ...

  3. 类文件结构-----Class类文件的结构

    ①无关性的基石 “与平台无关的”得理想最终实现在操作系统的应用层上:Sun公司和其他虚拟机提供商发布了许多可以在各种不同平台上的虚拟机,这些虚拟机都可以载入和执行同一种平台无关的字节码,从而实现了程序 ...

  4. 关于Tomcat的点点滴滴(体系架构、处理http请求的过程、安装和配置、文件夹结构、设置压缩和对中文文件名称的支持、以及Catalina这个名字的由来……等)

    总结Tomcat的体系架构.处理http请求的过程.安装和配置.文件夹结构.设置压缩和对中文文件名称的支持.以及Catalina这个名字的由来--等. Tomcat和JVM: 一个Tomcat仅仅会启 ...

  5. 插件化框架解读之Class文件与Dex文件的结构(一)

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 Class文件 Class文件是Java虚拟机定义并被其所识别的 ...

  6. JVM内存模型和结构详解(五大模型图解)

    JVM内存模型和Java内存模型都是面试的热点问题,名字看感觉都差不多,实际上他们之间差别还是挺大的. 通俗点说,JVM内存结构是与JVM的内部存储结构相关,而Java内存模型是与多线程编程相关@mi ...

  7. 如何组织较大项目的MVC文件夹结构

    现在还用不到,拷贝下来备用,原文链接 2016 年 9 月 第 31 卷,第 9 期 ASP.NET Core - ASP.NET Core MVC 的功能切分 作者 Steve Smith | 20 ...

  8. Class类文件的结构

    Class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件中,中间没有任何分隔符.Class文件的结构只有两种数据类型:无符号数和表.无符号数以u1.u2. ...

  9. 认识html文件基本结构

    html文件的结构:一个HTML文件是有自己固定的结构的. <html> <head>...</head> <body>...</body> ...

  10. JVM运行时内存结构

    原文转载自:http://my.oschina.net/sunchp/blog/369707 1.JVM内存模型 JVM运行时内存=共享内存区+线程内存区 1).共享内存区 共享内存区=持久带+堆 持 ...

随机推荐

  1. mysql聚簇索引和非聚簇索引

    聚簇索引 InnoDB使用的是聚簇索引 将数据与主键索引放在了一起,索引的叶子节点保存了行数据,找到了主键索引,即找到了行数据. 辅助索引记录了主键的位置,所以查询where name= xxx 时, ...

  2. gunicorn简单配置

    Gunicorn配置 # -*- coding: utf-8 -*- import os from multiprocessing import cpu_count bind = "127. ...

  3. 用正则怎么将html文件中文字取出进行ASCII码转换?

    用正则怎么将html文件中文字取出?今天碰到这个问题,思来想去尝试了好几种方法,历经一阵头脑风暴,最后终于还是解决了,想想还是来记录一下.一共定义了三个函数,包含正则切割.正则判断对象开头.ASCII ...

  4. 参数文件恢复:RMAN-0617

    RMAN> restore spfile from autobackup; Starting restore at 03-APR-19using channel ORA_DISK_1using ...

  5. js处理浏览器兼容

    1.try  catch 在try中执行我们的代码,如果在执行的过程中发生了异常信息,我们在catch中写代替的执行方案 前提:不兼容四位情况下,执行对应的代码,需要发生异常错误才可以检测到 弊端:不 ...

  6. css 11-CSS3属性详解(一)

    11-CSS3属性详解(一) #前言 我们在上一篇文章中学习了CSS3的选择器,本文来学一下CSS3的一些属性. 本文主要内容: 文本 盒模型中的 box-sizing 属性 处理兼容性问题:私有前缀 ...

  7. 移动端SCSS

    一.什么是SASS SASS是一种强化CSS的辅助工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单可维护. #二.安装和使用(VS Code中) #1.安装 下载扩展文件 ...

  8. DRF类视图让你的代码DRY起来

    刚开始写views.py模块的代码,一般都是用def定义的函数视图,不过DRF更推荐使用class定义的类视图,这能让我们的代码更符合DRY(Don't Repeat Yourself)设计原则: 使 ...

  9. Animate..css的一些属性使用

    使用基本的代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <t ...

  10. Linux系列之Centos安装

    http://mirrors.aliyun.com/centos/6/isos/x86_64/可下载iso文件 第一步 笔记本进入BIOS开启虚拟化 第二步 进入vmware官网下载vm,作者用的是v ...