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 01a 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文件

jclasslib 解析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的两个索引
    在这里插入图片描述
  • 00 03 :表示常量池的索引位置,十进制为3,表示常量池中的3号常量,即
    在这里插入图片描述
  • 00 0D :表示常量池的索引位置,十进制为13,表示常量池中的13号常量,即
    在这里插入图片描述
    至此,第一个常量池中第一个位置的CONSTANT_Methodref_info分析完了,接下来的16进制数表示,第二个位置的,我们继续分析:
  • 07 :常量池中下一个类型的tag,十进制值为7,即CONSTANT_Class_info
    在这里插入图片描述
  • 00 0E:两个字节的索引,表示指向类的全限定名项的索引,十进制值为14,常量池14号位置存放的如下图所示
    在这里插入图片描述
    1个字节表示常量池2号位置的类的全限定名称的字符串长度n,n个字节表示全限定名称字符串;
  • 往后依次解读完常量池部分
  • 再查看其后的方法部分
    在这里插入图片描述
    是指无参构造方法,Code描述的是十六进制数表示的对应代码的编号
  • 如 aload_0 这条指令
    在这里插入图片描述
    查Hotspot的JVM规范可知
    在这里插入图片描述
    aload_0 用0x2a表示,查class文件,发现2a在此处
    在这里插入图片描述
    下一个字节的B7也正是表示的 invokespecial 这条指令。再其后的两位 00 01 表示的是常量池1号位置的引用;
    在这里插入图片描述

常量池所有类型(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迭代不断增加…

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值