• .class文件结构解析


    工具

    我们可以使用javap -verbose,配合记事本来对照着看字节码文件

    .class文件结构

    class文件通过记事本打开,可以得到16进制的一个文件,其中结构如下:
    image
    image

    魔数

    4个字节,魔数固定为cafe baby

    副版本号

    2个字节,表示jdk的次版本号

    主版本号

    主版本号两个字节,假设为00 34,它的10进制为52,52代表的是1.8,51代表的是1.7,依此类推

    常量池计数器

    记录常量池数据区中常量的数量

    常量池数据区

    常量池数据区的数据数量是常量池计数器的数量-1。例如:常量池计数器为00 19转成10进制即为25,这个时候常量池数据区应该有24个常量。原因是第一个常量池JVM存了null

    常量池结构

    u1,u2,u4,u8分别代表1个字节,2个字节,4个字节,8个字节的无符号数
    image
    image
    常量池一般存放两种常量,字面量和符号引用
    image

    描述信息

    在JVM规范中,每个字段或者变量都有描述信息,描述信息的主要作用是 数据类型,方法参数列表,返回值类型等.
    1)基本参数类型和void类型都是用一个大写的字符来表示,对象类型是通过一个大写L加全类
    名表示,这么做的好处就是在保证jvm能读懂class文件的情况下尽量的压缩class文件体积.
    基本数据类型表示:
    B---->byte
    C---->char
    D---->double
    F----->float
    I------>int
    J------>long
    S------>short
    Z------>boolean
    V------->void
    对象类型:前面加一个L,然后把.改为/
    String------>Ljava/lang/String;(后面有一个分号)
    对于数组类型: 每一个唯独都是用一个前置 [ 来表示
    比如: int[] ------>[ I,
    String [][]------>[[Ljava.lang.String;
    用描述符来描述方法的,先参数列表,后返回值的格式,参数列表按照严格的顺序放在()中
    比如源码 String getUserInfoByIdAndName(int id,String name) 的方法描述符号
    (I,Ljava/lang/String;)Ljava/lang/String;

    访问标识

    解析我们的class文件是类还是接口,是否定义为public的,是否是abstract,是否被final修饰
    image
    两个访问修饰符直接通过位运算来实现的。
    例如现在有一个class文件访问标识为00 21。那么实际它代表的是0x0021 = 0x0020 位运算 0x0001,即它代表这个class的访问权限是ACC_PUBLIC和ACC_SUPER

    类索引

    描述当前所属的类,它存储着常量池中的位置,例如00 03,就代表这个索引指着常量池中第三个常量,那么第三个常量的名称就是这个类的名称。

    父类索引

    当前类的父类名字,同类索引,存的也是常量池中的位置。

    接口计数器

    计数,记录实现了几个接口

    接口信息计数区

    会存位于常量池中的索引,同类索引和父类索引

    字段信息

    同样的,前两位为字段的数量,后面就是n个字段,它的作用是描述类和接口中声明的变量,包括类变量和实例变量,但是不包括方法的局部变量
    字段的结构如下:
    image
    假设有个字段在class文件中为00 02 00 05 00 06 00 00
    所以00 02 表示访问修饰符号为ACC_PRIVATE
    所以00 05 表示的是字段的名称 指向的是常量池中第五个常量
    所以00 06是我们的字段的描述符: 指向的是常量池中第六个常量
    00 00 表示是属性表的个数 这里为0表示后面是没有属性表集合

    方法信息

    方法与字段类似,其结构如下:
    image
    假设有个方法在class文件中为 00 01 00 07 00 08 00 01
    00 01:表示的是方法的修饰符 表示的是acc_public
    00 07:表示的是方法的名称 表示指向常量池中第7个常量,表示方法的名称
    00 08:方法的描述符号,表示指向常量池第八个常量
    00 01表示有一个方法属性的个数
    注意:表示构造方法;为()V 表示的是无参无返回值

    方法表中的属性表attribute_info结构图

    image

  • 相关阅读:
    日记2014/06/25
    Cocos2dx 3.1.1 学习笔记整理(4):事件监听与Action的初步使用
    Cocos2dx 3.1.1 学习笔记整理(3):逐帧动画
    Cocos2dx 3.1.1 学习笔记整理(2):创建场景与载入图片
    Cocos2dx 3.1.1 学习笔记整理(1) 新建项目
    5-20
    5-19
    5-18
    5-17
    5-16
  • 原文地址:https://www.cnblogs.com/gdvxfgv/p/16015293.html
Copyright © 2020-2023  润新知