java字节码文件

作者: 快点给我想个名 | 来源:发表于2019-09-26 20:50 被阅读0次

参考链接:美团技术团队

使用javap -verbose命令分析一个字节码文件时,将会分析该字节码文件的魔术、版本号、常量池、类信息、类的构造方法、类中的方法信息、类变量与成员变量等信息。


字节码.png
java字节码整体结构
image.png
魔术
  • 所有的.class文件的前四个字节都是魔数,魔数的固定值为:0xCAFEBABE。魔数放在文件开头,JVM可以根据文件的开头来判断这个文件是否可能是一个.class文件,如果是,才会继续进行之后的操作。
版本号
  • 版本号为魔数之后的4个字节,前两个字节表示次版本号(Minor Version),后两个字节表示主版本号(Major Version)。上图2中版本号为“00 00 00 34”,次版本号转化为十进制为0,主版本号转化为十进制为52,在Oracle官网中查询序号52对应的主版本号为1.8,所以编译该文件的Java版本号为1.8.0。
常量池
  • 紧接着主版本号之后的字节为常量池入口。一个java类中定义的很多信息都是由常量池来维护和描述的,可以将常量池看作是Class文件的资源仓库,比如Java类中定义的方法与变量信息,都是存储在常量池中。常量池中存储两类常量:字面量与符号引用。
  • 字面量:代码中声明为Final的常量值。
  • 符合引用:符号引用如类和接口的全局限定名、字段的名称和描述符、方法的名称和描述符。
  • 常量池总体结构:Java常量池整体上分为两部分:常量池数量(常量池计数器)与常量池数组(常量池数据区)构成。常量池数量紧跟在主版本号后面,占据2个字节;常量池数组则紧跟在常量池数组之后。常量池数组中元素的类型和结构是不同的。每一种元素的第一个数据都是一个u1类型,该字节是一个标志位,占据1个字节。JVM在解析常量池时,会根据这个u1类型来获取元素的具体类型。常量池数组中元素的个数= 常量池数 - 1,目的是满足某些常量池索引值的数据在特定情况下需要表达【不引用任何一个常量池】的含义:根本原因在于,索引为0也是一个常量,只不过它不在常量表中,这个常量就对应null值,所有,常量池的所有从1开始而不是0。


    常量池结构.png
  • 在字节码中共有14种类型的cp_info(如下图6所示),每种类型的结构都是固定的


    image.png
  • 在JVM规范中,每个变量/字段都有描述信息,描述信息主要的作用是描述字段的数据类型、方法的参数列表(包括数量、类型与顺序)与返回值。根据描述规则,基本数据类型和代表无返回值的void类型都用一个大写字母表示,对象类型则使用字符L加对象的全限定名称来表示。为了压缩字节码文件的体积,对于基本数据类型,JVM都只使用一个大写字母来表示,如下所示: B--byte、C--char、D--double、F--Float、I--int、J--long、S--short、Z--boolean、V--void、 L--对象类型,如 Ljava/lang/String; 。
  • 对于数组类型来说,每一个维度使用一个前置的[来表示,如int[]被记录为[I,Stirng[][]被记录为[[Ljava/lang/String; 。
  • 用描述符描述方法,按照先参数列表,后返回值得顺序来描述,参数列表按照参数的严格顺序放在一组()之内,如方法: String getCardByIdAndName(int id,String name)的描述符为: (I,Ljava/lang/String;)Ljava/lang/String; 。
访问标志

描述该Class是类还是接口,以及是否被Public、Abstract、Final等修饰符修饰。


访问标志.png
类索引、父类索引、接口索引

字段表

用于描述类和接口中声明的变量。这里的字段包含了类级别变量以及实例变量。但是不包括方法内部声明的局部变量。字段表也分为两部分,第一部分为两个字节,描述字段个数;第二部分是每个字段的详细信息fields_info。字段表结构如下图所示:


字段表.png
  • fidles_info结构


    fidles_info.png
方法表

字段表结束后为方法表,方法表也是由两部分组成,第一部分为两个字节描述方法的个数;第二部分为每个方法的详细信息。方法的详细信息较为复杂,包括方法的访问标志、方法名、方法的描述符以及方法的属性,如下图所示:


方法表.png
  • method_info结构


    method_info.png
  • attribute_info结构


    attribute_info.png
Code结构

Code attribute的作用是保存该方法的结构,如下图所示:


Code attribute.png
  • attribute_length表示attribute锁包含的自己数,不包含attribute_name_index和attribute_length字段。
  • max_stack表示这个方法运行的任何时刻所能达到的操作数栈的最大深度。
  • max_loacls表示方法执行期间创建的局部变量的数目,包含用来表示传入的参数的局部变量。
  • code_length表示该方法锁包含的字节码的字节数以及具体的指令码。 具体字节码即是该方法被调用时,虚拟机锁执行的字节码。
  • exception_talbe这里存放的是处理异常的信息。每个eception_table表项由start_pc,end_pc,handler_pc,catch_type组成。
  1. start_pc和end_pc表示在code数组中的从start_pc到end_pc处(包含start_pc,不包含end_pc)的指令抛出的异常会由这个表项来处理。
  2. handler_pc表示处理异常的代码的开始处。
  3. catch_type表示会被处理的异常类型,它指向常量池里的一个异常类。当catch_type为0时,表示处理所有的异常。

相关文章

  • 新鲜出炉,深入讲解java反射的底层原理,这篇算讲的不错了!

    反射 反射 Java代码和Java文件 Java文件和.class字节码文件 class字节码文件在内存中的位置 ...

  • Java字节码

    Java字节码 编辑.java文件,生成字节码文件 反编译字节码文件 源代码中的各种变量,关键字和运算符号的语义最...

  • Java基础1-5问

    01 Java源程序文件的后缀是?Java字节码文件的后缀名称是? Java源程序后缀是【.java】,字节码文件...

  • Effect JAVA -机制与原理

    JAVA字节码.Class解析 不论该字节码文件来自何方,由哪种编译器编译,甚至是手写字节码文件,只要符合java...

  • 03 java字节码文件

    java源码经过编译,生成class字节码文件,JVM加载class文件执行。字节码文件将java语言与JVM解耦...

  • android 虚拟机

    java:.java文件编译成.class文件的字节码,最终将字节码提供给jvm翻译成机器码。 android:....

  • JVM

    JVM 基础-类字节码详解 多语言编译为字节码在 JVM 运行 Java 字节码文件-- Class文件的结构属性...

  • java运行时数据区

    java程序在执行之前被编译成字节码文件,再由java虚拟机执行这些字节码文件是的java程序得以运行。java虚...

  • 乱七八糟的基础知识

    JAVA编译过程 源文件—>java编译器—>字节码文件—>(类装载器—>字节码校验器—>解释器)—>系统平台 字...

  • AndroidStudio配置生成java字节码

    有时候需要使用到java的字节码,参考了相关的博客,如这个:将java文件编译成字节码文件,再到反编译,字节码指令...

网友评论

    本文标题:java字节码文件

    本文链接:https://www.haomeiwen.com/subject/qpljyctx.html