class文件的加载过程(真正理解class文件的常量池)
class文件的加载过程(真正理解class文件的常量池)
2024-11-25 12:33:35  作者:志在千里  网址:https://m.xinb2b.cn/sport/vjg505419.html

class文件常量池可以说是class的资源库,可以说它包含所有class文件需要的字符

再看class文件结构

再次引入class文件结构图如下图:


在上一篇文章中分析了class文件的前三个结构magic、minor_version、major_version,这三个结构除了主版本跟随jdk版本变化外其他都是固定不变的,是class文件的的基础。

紧接着的结构是constant_ pool_count、constant_ pool常量池数量与常量池,常量池数量u2类型的结构,暂用两个字节,里面的内容表示接下来会有多少个常量。

constant_ pool可以把他想成一个数组,他的长度是constant_ pool_count-1,因为constant_ pool是从1开始计数的,第0项作为预留可以表示什么都没有的意思,比如后面有索引要指向常量池的数据,但是实际值是不存在,则可以指向0(写在这里可能难以理解,不过等看完这篇文章在回头来看应该就理解了)。

常量池数据结构

前面的结构通过固定暂用几个字节就表达需要表达的含义,而接下来的常量池则要表达的内容要多得多,所以不是仅仅通过固定的几个字节就能够编译出二进制表达的含义,而是通过定义一些常量类型来表示,每个常量类型它有自己的独特结构以此来表达它的含义,常量池类型发展至今已经有17个,下图是常见的11个。

常见的11个常量池类型如下图:


常量列表示他的名字不在class文件中表示,项目表示每个常量类型的结构,tag表明常量类型,byte表示常量项包含的具体内容。第一项CONSTANT_Utf8_info表达的是一个字符串,包含一个length结构表示这个字符串有多少个字节组成。还有一些项目包含index结构,表示他是通过引用常量池的其他常量项来表达(下一节分析具体示例能更加理解)。类型表示各个常量项各个结构暂用的字节数。

常量池示例分析

还是按照上一篇文章的class文件继续分析,文件内容图如下图:


上一篇文章我们分析了前8个字节"CA FE BA BE 00 00 00 34",通过前面两节的分析我们知道接下来两个字节是constant_ pool_count,"00 18"转换成10进制是24,所以说明接下来有24-1=23个常量项

接下来的内容就该是常量项:

我们知道常量项最前面的结构都是tag都占一个字节,所以"0A"表示第一个字节的tag,十进制表示是10,通过查表知道tag等于10的常量类型是CONSTANT_Methodref_info(结构tag U1;index U2;index U2),说明这个常量表达的是一个方法的表达式,同时通过结构知道接下来的2个字节表达的方法的类描述符所在的常量项,"00 04"说明常量池第4项是这个方法的类描述符,接下来两个字节是方法的名称和类型,"00 14"十进制是20说明常量池第20个常量;

第2个常量池tag"09"表示这个常量项是CONSTANT_Fielderf_info(结构tag U1;index U2;index U2)类型,然后接下来4个字节"00 03 00 15"说明这个字段的类和描述符分别存在常量池的第3、21项;

第3个常量池tag"07"表示CONSTANT_Class_info(tag U1;index U2)是一个类的全限定名称,接下来两个字节"00 16"表示类的全限定名称在常量池第22项;

第4个tag"07"和上一个一样,"00 17"表示类的全限定名称在常量池第23项;

第5个tag"01"表示CONSTANT_Utf8_info(tag U1;length U2;byte U1)是用来表达字符串的,接下来2个字节"00 04"表示字节长度,说明接下来4个字节都是字符串的内容"76 61 72 31",通过ASCII表查询结果为var1,这是因为我在类中定义了一个变量var1;

第6个tag"01",又是一个字符串,长度为"00 01",内容"49",ASCII表查询结果I;

第7个tag"01",长度"00 06",内容"3C 69 6E 69 74 3E",结果<init>,在字节码里面构造方法就是<init>,这个后面说明;

第8个tag"01",长度"00 03",内容"28 29 56",结果()V,在字节码里用来表达方法无参数返回值为void,与<init>()V可以表达一成一个无参构造方法;

第9个tag"01",长度"00 04",内容"43 6F 64 65",结果Code;

第10个tag"01",长度"00 0F",内容"4C 69 6E 65 4E 75 6D 62 65 72 54 61 62 6C 65",结果LineNumberTable;

第11个tag"01",长度"00 12",内容"4C 6F 63 61 6C 56 61 72 69 61 62 6C 65 54 61 62 6C 65 ",结果LocalVariabletable;

第12个tag"01",长度"00 04",内容"74 68 69 73",结果this;

第13个tag"01",长度"00 1E",内容"4C 63 6F 6D 2F 64 67 67 63 63 2F 74 65 73 74 2F 6C 65 69 2F 43 6C 61 73 73 54 65 73 74 3B",结果"Lcom/dggcc/test/lei/ClassTest;";

第14个tag"01",长度"00 07",内容"67 65 74 56 61 72 31",结果getVar1;

第15个tag"01",长度"00 03",内容"28 29 49",结果()I;

第16个tag"01",长度"00 07",内容"73 65 74 56 61 72 31",结果setVar1;

第17个tag"01",长度"00 04",内容"28 49 29 56",结果(I)I;

第18个tag"01",长度"00 0A",内容"53 6f 75 72 63 65 46 69 6c 65",结果SourceFile;

第19个tag"01",长度"00 0E",内容"43 6C 61 73 73 54 65 73 74 2E 6A 61 76 61",结果ClassTest.java;

第20个tag"0C"表示12对象常量类型CONSTANT_NameAndType_info(tag U1;length U2;byte U2),表示字段或者方法的名称和描述,接下来4个字节"00 07 00 08",分别是常量池的第7、8项,结果为<init>:()V;

第21个tag"0C"与上一个类型一样,接下来4个字节"00 05 00 06",分别是常量池的第5、6项,结果为var1:I;

第22个tag"01",长度"00 1C",内容"63 6F 6D 2F 64 67 67 63 63 2F 74 65 73 74 2F 6C 65 69 2F 43 6C 61 73 73 54 65 73 74",结果com/dggcc/test/lei/Classtest;

第23个tag"01",长度"00 10",内容"6A 61 76 61 2F 6C 61 6E 67 2F 4F 62 6A 65 63 74",结果java/lang/Object;

至此常量池数据分析完成,可以再返回去分析出前4个常量包含的内容,可以看出每个常量项要么直接表达出包含内容,要么通过指向常量池的一项或多项来组合成表达的结果,在idea通过javap -verbose com.dggcc.test.lei.ClassTest验证结果,结果如下图:


总结

这里由于这个类比较简单,所以常量池较少,不过基本常见的结构都已经包含了,可以看出常量池中主要保存的是一些字符串,或者多个常量池字符串组合。到目前为止可能还看不出来常量池的作用,不过通过存储的内容也可以大概猜出,它基本包含了接下来为了表达用户代码所需要的字符串。

字节码文件的分析到目前为止已经过半,却还没有涉及到用户代码,不过常量池分析完成也就是用户代码编译的基础已经完成,接下来就可以继续分析用户代码了,下一篇文章继续!

Java程序员日常学习笔记,如理解有误欢迎各位交流讨论!


  • 失恋后必听的10首歌曲 推荐几首适合失恋听的歌曲
  • 2024-11-25失恋后必听的10首歌曲 推荐几首适合失恋听的歌曲恋爱是甜蜜的,失恋是痛苦的,如何迅速摆脱痛苦,不再沉沦,可以借助音乐来帮助自己迅速摆脱失恋那么有哪些歌曲适合失恋时候听呢萧亚轩《一个人的精彩》这首歌写的太好了“挥手拜拜祝你们愉快,我会一个人活得精彩”。
  • 哥斯拉2怪兽之王 简介(哥斯拉2怪兽之王曝新怪兽数据)
  • 2024-11-25哥斯拉2怪兽之王曝新怪兽数据美国这两天正在举行一年一度的WonderCon,展会上会有各大电影公司专门宣传自己旗下的大片,其中《哥斯拉2:怪兽之王》就在会上曝光了一些新的信息,主创不仅在会上发布了前传漫画的一些信息,还在会上曝光。
  • 菱角怎么剥壳(菱角剥壳的方法)
  • 2024-11-25菱角剥壳的方法生菱角的剥法:将生菱角用清水洗净,然后将菱角的底部剪个口子,两侧用刀切掉但是不要切得太多,看的到菱角肉即可,然后将双手放在菱角的两边,用力一掰即可熟菱角的剥法:将煮熟的菱角的两个角用刀切掉,然后沿着菱。
  • 范冰冰薄纱裙穿搭(范冰冰真敢秀用紧身裙穿出)
  • 2024-11-25范冰冰真敢秀用紧身裙穿出​连衣裙可谓是女孩们的最爱了,它的款式多种多样,不论是日常的休闲场合还是参与重要的约会,连衣裙都是不会让你失望的选择对于娱乐圈的女星们来说,一件合身的连衣裙更是吸引目光的利器,范冰冰就用紧身连衣裙高调。
  • 他为拍戏增肥30斤如今靠轮椅出行(身高不足一米二)
  • 2024-11-25身高不足一米二在演艺圈有这样一位“特型演员”,他其貌不扬,身高不足1米2,出道快20年遭受过无数嘲笑,看过无数白眼,如今成了知名矮星,和姜文、刘德华、葛优等娱乐圈超级大腕都是好友,还娶了比他小18岁并且比他高很多的。
  • 求婚大作战第一集讲解(求婚大作战首播就放大招)
  • 2024-11-25求婚大作战首播就放大招由张艺兴领衔主演的青春校园爱情剧《求婚大作战》,著名导演毛小睿执导,金牌制作人崔轶打造,张艺兴、陈都灵领衔主演,李程彬、张昊唯、赵圆瑗、吕炸炸联合主演,张智霖特邀主演的校园爱情剧《求婚大作战》,日前已。
  • 电影寄生虫独特之处(也讲过寄生虫里的故事)
  • 2024-11-25也讲过寄生虫里的故事​本周最火的电影,必须提到《寄生虫》,真的是牵动所有影迷的爆款啊!此前,对于这部爆款电影我们也做了推荐(戳这里回顾)回想起来,电影在内容上已经足够出众,却更在制作的各个层面上达到了某种极致真正让这部电。
  • 漫威灭霸战斗(漫威假如第2集灭霸洗白)
  • 2024-11-25漫威假如第2集灭霸洗白千呼万唤,这周的漫威《假如》脑洞衍生剧终于是更新了~相比较此前第1集中“卡特队长”的开胃菜剧情来说,第2集中上线的“黑豹版星爵”结合了“银河护卫队”的世界观背景,给了漫威粉丝一个非常大的惊喜,而且,在。
  • 索尼fx3报价(索尼发布迄今最小电影机FX3)
  • 2024-11-25索尼发布迄今最小电影机FX3来源:快科技2月23日晚,索尼正式发布全画幅电影摄影机FX3(型号名:ILME-FX3),它是索尼目前最为紧凑和小巧的电影摄影机,定价32000元人民币作为索尼电影摄影机系统的最新产品,FX3汇集了索。
  • 一百斤鱼是多少克
  • 2024-11-25一百斤鱼是多少克一百斤鱼等于50000克斤也是衡量重量的单位,斤为中国特有的重量衡量单位重量单位之间的相互换之间换算吨=1000公斤,1000公斤=1000千克,一千克=一公斤,一公斤=2斤,2斤=1000克,1斤就。
  • 王者荣耀女生简单气质(王者荣耀文艺名字)
  • 2024-11-25王者荣耀文艺名字银笺别梦山川无恙川岛奈樱子.欲倒湖倾青梅煮马月亮失了约.陌颜飘渺如烟慬夏婉安旧街浪人一语呢喃诗伴酒清宁时光夏初花未谢°未央几寒星星打烊.七夏.夏寒难平眉緋若紫辰风扬起的思念青花凉薄.云柯樱花已落暮雨尘。