• 类文件结构


    1.Class类文件结构

           Class文件是一组以8个字节为基础单位的二进制字节流,各个数据项目严格按照顺序紧凑地排列在文件之中,中间没有添加任何分隔符,Class文件格式采用一种类似于C语言结构体的伪结构来存储数据

    这种伪结构中只有两种数据类型:“无符号数”与“表”

    • 无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节、8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值
    •  表是由多个无符号数或者其他表作为数据项构成的复合数据类型,为了方便区分,所有的表命名都习惯的以“_info”结尾,表用于描述有层次关系的复合结构的数据

    1.1 魔数与class文件的版本

           每个Class文件的头4个字节被称之为魔数,它的唯一作用是确定这个文件是否为一个能被虚拟机接收的Class文件,魔数的值为“0xCAFEBABE”,紧接着魔数的4个字节存储的是Class的版本号,第5、6个字节存储的是次版本号(Minor Version),第7、8个字节存储的是主版本号(Major Version)

    1.2 常量池

             紧接着主、次版本号之后就是常量池入口,常量池可以比喻为Class文件里的资源仓库,它是Class文件结构中与其他项目关联最多的数据,也是在Class文件中出现的第一个表类型数据项目

    常量池中主要存放两大类常量:

    1. 字面量(字面量比较接近与Java语言层面的常量概念,如文本字符串以及被声明final的常量值等)
    2. 符号引用(而符号引用则属于编译原理方面的概念,主要包括以下几类常量:
    • 被模块导出或者开放的包
    • 类和接口的全限定名
    • 字段的名称和描述符
    • 方法的名称和描述符
    • 方法句柄和方法类型
    • 动态调用点和动态常量

            Java代码在进行Javac编译的时候,不像是C或者C++那样有“连接”这一步骤,而是在虚拟机加载Class文件的时候进行动态连接,也就是说,在Class文件中不会保存各个方法、字段最终在内存中的布局信息,这些字段、方法的符号引用不经过虚拟机在运行期转换的话无法的到真正的内存入口地址,也就是无法直接被虚拟机使用的,当虚拟机做类加载的时候,将会在常量池获得对应的符号引用,再在类创建时或运行时解析、翻译到具体的内存地址之中

    1.3 访问标志

           在常量池结束之后,紧接着2个字节代表访问标志,这个标志用于识别一些类或者接口层次的访问信息,具体的标志图如下:

    标志名称标志值含义
    ACC_PUBLIC0x0001是否为public类型
    ACC_FINAL0x0010是否被声明为final,只有类可设置
    ACC_SUPER0x0020是否允许使用invokespecial字节码指令的新语义,JDK1.0.2时候编译出来的类这个标志都为真
    ACC_INTERFACE0x0200标识这是一个接口
    ACC_ABSTRACT0x0400是否为abstract类型
    ACC_SYNTHETIC0x1000标识这个类并非用户代码生成
    ACC_ANNOTATION0x2000标识这是一个注解
    ACC_ENUM0x4000标识这是一个枚举
    ACC_MODULE0x8000标识这是一个模块

    1.4 类索引、父类索引与接口索引集合 

             类索引父类索引都是一个u2类型的数据,而接口索引集合是一组u2类型的数据的集合,Class文件中由这三项数据来确定该类型的继承关系

            类索引用于确定这个类的全限定名,父类索引用于确定这个类的父类的全限定名(由于Java不允许多重继承,所以父类索引只有一个,除了Object之外,所有的java类都有父类,所有的父类索引都不为0)

    1.5 字段表集合

           字段表用于描述接口或者类中声明的变量,Java语言中的“字段”包括类级变量以及实例级变量,但不包括在方法内部声明的局部变量,一个字段可以包含哪些信息呢?

    • 有字段的作用域(public、private、protected修饰符)
    • 实例变量、类变量(static修饰)
    • 可变性(final)
    • 并发可见性(volatile修饰符)
    • 可否被序列化(transient修饰符)
    • 字段数据类型(基本类型、对象、数组)、字段名称

  • 相关阅读:
    3.Mybatis 注解方式的基本用法
    zabbix6自动化配置监控项监控GPU
    华为云CodeArts IDE for Java安装使用教程
    【笔记】申请域名(免费)、创建ssl证书(自签、免费)、自动续签
    玄机靶场 第二章日志分析-mysql应急响应
    初学phar反序列化
    Nginx反向代理&负载均衡
    浅谈wor2vec,RNN,LSTM,Transfermer之间的关系
    (原创)关于 获取 java的 文件路径心得
    数据库mysql实战
  • 原文地址:https://blog.csdn.net/dfdbb6b/article/details/133821502