Class文件结构

来源:互联网 发布:淘宝上买电器可靠吗 编辑:程序博客网 时间:2024/04/25 00:40

JVM原理 篇二


  1. 概述:Class文件是一组以8字节为基础单位的二进制流(JVM相当于一个虚拟的计算机,计算机只能识别0,1代码),各个数据项目都按照顺序进奏地排列在Class文件中,中间没有任何分隔号,节约内存。当遇到需要占用8位字节以上空间的数据项是按照高位在前的方式分割成若干个8位字节。Class文件采用只有无符号数和表的伪结构方式来存储数据。

    • 无符号数:用u1,u2,u4,u8分别代表1,2,4,8字节的无符号数,可以描述数字,索引引用,数量值,UTF-8编码字符创。

    • 表:由多个无符号数或者其他表作为数据项的符合数据类型,所有表都习惯以“_info”结尾。

  2. Class文件头:每个Class文件的头四个字节成为魔数(CAFEBABE),确定这个文件是否为一个能被虚拟机接受的Class文件.因为Class文件没有空隙存在,采取伪结构存储数据,所以只能规定一个数让JVM识别Class文件,识别出来才会加载。后面四个字节表示的是最小的版本号和最大的版本号,如果此Class文件的第5,6,7,8字节是0x00 00 00 30,则代表此Class文件只能被1.5及以上版本的虚拟机加载。JVM在加载一个Class文件之前会去检查以上8个字节,看是否符合其标准,符合则加载。

  3. 常量池:常量池开始有一个u2类型数据(2字节)代表该类中常量的数
    量,容量计数是从1开始的,0是保留常量。常量池中主要存放两大类常量:字面量和符号引用。当虚拟机运行时要在常量池中获取符号引用和字面量(final修饰的常量,也是他之所以不可以改变其值得原因,因为直接保存其字面量值在常量池中,而不是引用),再在类创建时或者运行时解析,翻译得到具体的内存地址之中。常量池中的每一项常量都是一个表。每个表开始u1类型数据代表这一项常量是什么类型的常量,后两个字节代表了常量池索引。指向UTF-8类型常量或者其他类型。

    • UTF-8常量类型:第一个字节表示该常量是什么类型,后两个字节表示后面所存储的字符串的总字节数,再后面则是内容。
      这里写图片描述

    • Fieldref、Methodref:第3.4字节表示的是哪个类,类中此常量的位置
      这里写图片描述

    • Class常量类型:表示该类的名称,同样,指向另外一个UTF-8类型常量。
  4. 类信息:常量池后面就是关于类本身的信息描述(共8个字节),由两个字节表示这个类的访问控制描述;后面两个字节代表该类的名称;依次是父类的名称,接口的名称。

  5. Fields和Methods定义:前四个字节分别代表该类中定义了多少属性和多少方法;两个字节表示方法和属性的访问控制;接下来的四个字节代表的是方法的名称和描述,也就是NameType;接下来就是方法内部具体的代码实现的定义。两个字节的name代表接下来是方法的什么方面的定义,四个字节代表这个方法的代码长度;两个字节代表该方法操作数栈深度最大值;两个字节代表局部变量表所需的存储空间,单位是slot;如果发现超过这两个值,JVM就会拒绝加载。四个字节代表方法中的的命令有几个字节;两个字节代表方法中抛出的异常;接下来是方法中存在的代码属性描述,比如说,行号,Class文件和源码之间就是通过行号关联起来的。
  6. LineNumbertable:用于描述Java源代码和字节码之间的对应关系。默认生成到Class文件中,不是必须的,可以去掉(javac是使用 -g:none)。LineNumberTable中包含多个line a:b,a代表这行代码在源代码中的行号,b代表这行代码的第一条Class文件在此Class文件开始时的字节码偏移量。
  7. LocalVariableTable:用于描述栈帧中局部变量表中的变量和Java源码中定义的变量只能建的关系,默认生成,可以取消(-g:none).Start表示该变量被复制到局部变量表中,生命周期开始的字节码偏移量,Length指令表示作用范围覆盖的长度,index是这个局部变量在栈帧局部变量表中slot的位置。name_index和signature指向UTF-8型常量,分别代表局部变量的名字和类型。
0 0
原创粉丝点击