JVM基础知识(三)Class文件解析实例

前言

用一段示例代码来解析Class文件。

一、源码

package com.yhcookie.cxt.mytest;

public class Test01_ByteCode {
    public  Test01_ByteCode(){};
}

二、对应的Class文件(16进制)

  • CA FE BA BE 00 00 00 34 00 10 0A 00 03 00 0D 07 00 0E 07 00 0F 01 00 06 3C 69 6E 69 74 3E 01 00 03 28 29 56 01 00 04 43 6F 64 65 01 00 0F 4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65 01 00 12 4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 01 00 04 74 68 69 73 01 00 29 4C 63 6F 6D 2F 79 68 63 6F 6F 6B 69 65 2F 63 78 74 2F 6D 79 74 65 73 74 2F 54 65 73 74 30 31 5F 42 79 74 65 43 6F 64 65 3B 01 00 0A 53 6F 75 72 63 65 46 69 6C 65 01 00 14 54 65 73 74 30 31 5F 42 79 74 65 43 6F 64 65 2E 6A 61 76 61 0C 00 04 00 05 01 00 27 63 6F 6D 2F 79 68 63 6F 6F 6B 69 65 2F 63 78 74 2F 6D 79 74 65 73 74 2F 54 65 73 74 30 31 5F 42 79 74 65 43 6F 64 65 01 00 10 6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74 00 21 00 02 00 03 00 00 00 00 00 01 00 01 00 04 00 05 00 01 00 06 00 00 00 2F 00 01 00 01 00 00 00 05 2A B7 00 01 B1 00 00 00 02 00 07 00 00 00 06 00 01 00 00 00 04 00 08 00 00 00 0C 00 01 00 00 00 05 00 09 00 0A 00 00 00 01 00 0B 00 00 00 02 00 0C

三、解读该class文件

JVM基础知识(三)Class文件解析实例
图为 IDEA的jclasslib解析class文件图。

  • CA FE BA BE :magic,标识该class文件为java
  • 00 00:minor_version 副版本号 十进制值为0
  • 00 34:major_version 主版本号 十进制值为52,表示jdk 1.8
  • 00 10:常量池计数器 十进制值为16,表示当前常量池有16-1 个常量
  • 0A :表示常量池 第一个常量的类型(文后附常量池所有类型)十进制值为10,表示tag为10的类型,即CONSTANT_Methodref_info,后4个字节为CONSTANT_Methodref_info的两个索引
    JVM基础知识(三)Class文件解析实例
  • 00 03 :表示常量池的索引位置,十进制为3,表示常量池中的3号常量,即
    JVM基础知识(三)Class文件解析实例
  • 00 0D :表示常量池的索引位置,十进制为13,表示常量池中的13号常量,即
    JVM基础知识(三)Class文件解析实例
    至此,第一个常量池中第一个位置的CONSTANT_Methodref_info分析完了,接下来的16进制数表示,第二个位置的,我们继续分析:
  • 07 :常量池中下一个类型的tag,十进制值为7,即CONSTANT_Class_info
    JVM基础知识(三)Class文件解析实例
  • 00 0E:两个字节的索引,表示指向类的全限定名项的索引,十进制值为14,常量池14号位置存放的如下图所示
    JVM基础知识(三)Class文件解析实例
    1个字节表示常量池2号位置的类的全限定名称的字符串长度n,n个字节表示全限定名称字符串;
  • 往后依次分析…

常量池所有类型(1.8为例)

  • CONSTANT_Utf8_info : 最常用的
    tag : 1 – 占用一个字节空间
    length : UTF-8 字符串占用的字节数
    bytes:长度为length的字符串

  • CONSTANT_Integer_info :
    tag : 3 – 占用一个字节空间(下同,不加赘述)
    bytes:4个字节,Big-Endian (高位在前)存储的int值

  • CONSTANT_Float_info :
    tag : 4
    bytes:4个字节,Big-Endian 存储的float值

  • CONSTANT_Long_info :
    tag : 5
    bytes:8个字节,Big-Endian 存储的long值

  • CONSTANT_Double_info :
    tag : 6
    bytes:8个字节,Big-Endian 存储的double值

  • CONSTANT_Class_info :
    tag : 7
    index:2个字节 指向类的全限定名项的索引

  • CONSTANT_String_info :
    tag : 8
    index:2个字节 指向字符串字面量的索引

  • CONSTANT_Fieldref_info :
    tag : 9
    index:2个字节 指向声明字段的类或者接口描述符CONSTANT_Class_info的索引项
    index: 2个字节 指向字段描述符CONSTANT_NameAndType的索引项

  • CONSTANT_Methodref_info :
    tag : 10
    index:2个字节 指向声明方法的类或者接口描述符CONSTANT_Class_info的索引项
    index: 2个字节 指向字段描述符CONSTANT_NameAndType_info的索引项

  • CONSTANT_InterfaceMethodref_info :
    tag : 11
    index:2个字节 指向声明方法的类或者接口描述符CONSTANT_Class_info的索引项
    index: 2个字节 指向字段描述符CONSTANT_NameAndType_info的索引项

  • CONSTANT_NameAndType_info :
    tag : 12
    index:2个字节 指向该字段或方法名称常量项的索引
    index: 2个字节 指向该子弹或方法描述符常量项的索引

  • CONSTANT_MethodHandle_info :
    tag : 15
    reference_kind:1个字节 1-9之间的一个值,决定了方法句柄的类型。方法句柄类型的值表示方法句柄的字节码行为
    reference_index: 2个字节 对常量池的有效索引

  • CONSTANT_MethodType_info :
    tag : 16
    descriptor_index:2个字节 指向Utf8_info结构 表示的方法描述符

  • CONSTANT_InvokeDynamic_info :
    tag : 18
    bootstrap_methed_attr_index:2个字节 当前Class文件中淫荡方法标的bootstrap_methods[]数组的有效索引
    name_and_type_index: 2个字节 指向NameAndType_info表示的方法名和方法描述符

随JDK迭代不断增加…

上一篇:win10选择文件的打开方式出错:该文件没有与之关联的应用来执行该操作


下一篇:市场上各个品牌琳琅满目,65寸智能电视怎么选?