一、常量池的内容

一个java类中定义的很多信息都是由常量池来维护和描述的,可以将常量池看作是class文件的资源仓库,比如java类中定义的方法与变量信息。常量池中主要存储两类常量:字面量(文本字符串,final的常量)与符号引用(类和接口的全限定名,字段的名称和描述符,方法的名称和描述符

一、常量池的结构

二、常量池的分析

常量池(也称常量表):主版本号之后就是常量池的开始位置;java类所对应的常量池主要由常量池数量和常量池数组两部分组成,常量池数量是主版本号之后的两个字节;常量池数组在常量池数量之后,常量池数组中不同元素的类型,结构是不同的,所以该数组长度是不同的,但是数组中的每一种元素的第一个字节是标记位是一个u1类型,JVM在解析常量池时会根据这u1类型来获取元素的具体类型。

1、常量池元素的数量:

00 18(24):就是该class字节码文件的常量池数量; 常量池数组元素的个数=常量池数量-1;索引为0的位置暂不使用,目的是满足某些常量池索引值的数据在特定情况下需要表达,不引用任何一个常量池的含义。根本原因是索引为零也是一个常量,只是他不在常量池中,该常量对应null值,所以常量池的索引从1开始(#1)。

 2、常量池数组

第一个元素:根据Constant pool 中 #1的描述可知该元素是无参的构造函数

0A(10):常量池元素数量之后的第一个字节,u1=10 对应

第一个u2(4):占两个字节即00 04;第二个u2(20):占两个字节即00 14;所以该常量池的第一个元素占五个字节即0A 00 04 00 14

第二个元素:根据 Constant pool  中#2的描述可知该元素是在类ByteCodeTest中一个int 类型 名字为num的变量,

09(9):第一个元素之后的第一个字节 ,u1=9 对应

第一个u2(3):占两字节00 03;第二个u2(15):占两个字节00 15;所以该常量池的第二个元素占五个字节即09 00 03 00 15

第三个元素:根据 Constant pool  中#3 可知该元素是该类的权限定名。

07(7):第二个元素之后的第一个字节07 ,u1=7 对应

u2(16):占两个字节00 16;所以该常量池的第三个元素占三个字节即07 00 16

第四个元素:根据 Constant pool  中#4 可知该元素是该Object类的权限定名。

07(7):第三个元素之后的第一个字节07 ,u1=7 对应

u2(17):占两个字节00 17;所以该常量池的第四个元素占三个字节即07 00 17

第五个元素:根据Constant pool  中#5的描述该元素是字符num

01(1):第四个元素之后的第一个字节01 ,u1=1 对应

u2(03):占两个字节00 03,表示utf-8格式的内容对应的长度是3个字节;u1:对应三个字节 6e  75 6d, 所以该常量池的第五个元素占6个字节即01 00 03 6e 75 6d;0x6e756d转字符串=num;

Hex转字符串工具

第六个元素:根据Constant pool  中#5的描述该元素是字符I

01(1):第五个元素之后的第一个字节01 ,u1=1 对应

u2(01):占两个字节00 01,表示utf-8格式的内容对应的长度是1个字节;u1(73):对应1个字节 49; 所以该常量池的第刘个元素占4个字节即01 00 01 49;49转十进制73;

根据ASCII字码表可知49=73=I;

其他元素分析方式与此相同就不再分析,最终分析可知红圈这部分区域是常量池的内容(00 18->63 74)

三、JVM描述符

在jvm规范中,每个变量或字段都有描述信息,描述信息主要的作用是描述字段的数据类型,方法的参数列表(包括数量,类型与顺序)与返回值。
1、为了压缩字节码文件的体积,JVM对于基本数据类型和代表无返回值的void类型都用一个大写字符来表示,而对象类型用字符L加对象的全限定类名来表示
如下表示:B--byte,C--Char,D--double,F--float,I--int,J--long,S--short,Z--boolean,V--void,L--对象类型如Ljava/lang/String。

2、对于数组来说,每一个维度使用一个前置的[来表示,如Int[]表示为[I,String[][]表示为[[Ljava/kang/Stirng;

3、用描述符来描述方法时,用先参数列表后返回值的顺序来描述,参数列表按照参数的严格顺序放在一组()之内,如方法:String getNameById(int id,String name)的描述符为:(I,Ljava/lang/String) Ljava/lang/String;

    public String getNameById(int id,String name){
return name;
}

最新文章

  1. ListDefinition Tips
  2. wildfly jobss 同时连接多个数据源
  3. TCP/IP 小知识
  4. Table '.\mysql\proc' is marked as crashed and should be repaired 报错
  5. VS2013密匙
  6. spoj 839 Optimal Marks(二进制位,最小割)
  7. UVa10895 Placing Lampposts
  8. java中一直说一个汉字使用两个字节,原来是不准确的
  9. float的理解
  10. 关于高性能javascript 笔记
  11. AspNet Core Api Restful +Swagger 实现微服务之旅 (三)
  12. Wincc flexable的局势视图的组态
  13. css direction 属性简介与实际应用。
  14. CBSN NEWS
  15. axios 安卓低版本兼容性处理
  16. Docker系列教程05 容器常用命令
  17. Linux中执行脚本参数获取
  18. Atitit 纯java项目的提升进度大法---通用json dsl接口
  19. NetStream 记录
  20. css 设置滚动条的样式

热门文章

  1. 树状数组(Binary Index Tree)
  2. oracle函数 REPLACE(c1,c2[,c3])
  3. IP应用加速技术详解:如何提升动静混合站点的访问速率?
  4. 「HNOI2015」菜肴制作
  5. 第三期 行为规划——4.形式化FSM
  6. Libev源码分析09:select突破处理描述符个数的限制
  7. 图表echarts折线图,柱状图,饼状图
  8. Oracle - @和@@、&与&& 的区别
  9. CondaHTTPError: HTTP 000 CONNECTION FAILED
  10. Java反射机制(一):认识Class类