一张图分析类的字节码结构
什么是class
Class文件是一组以8个字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑地排列在文件之中,中间没有添加任何分隔符,这使得整个Class文件中存储的内容几乎全部是程序运行的必要数据,没有空隙存在。当遇到需要占用8个字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8个字节进行存储。
无符号数属于基本的数据类型,以u1、u2、u4、u8来分别代表1个字节、2个字节、4个字节和8个字节的无符号数,无符号数可以用来描述数字、索引引用、数量值或者按照UTF8编码构成字符串值。
表是由多个无符号数或者其他表作为数据项构成的复合数据类型,为了便于区分,所有表的命名都习惯性地以info结尾。表用于描述有层次关系的复合结构的数据,整个Class文件本质上也可以视作是一张表,这张表数据项按严格顺序排列构成。
接下来以个实际的class来分析类的字节码结构。先来看看一个简单的类publicclassJavapTest{privateintcount;publicintsum(intx){countx;returncount;}staticclassTest{Stringxtest;}}
通过javap可得到下面内容publicclasscom。zl。basic。JavapTestminorversion:0majorversion:52flags:ACCPUBLIC,ACCSUPERConstantpool:1Methodref4。18javalangObject。init:()V2Fieldref3。19comzlbasicJavapTest。count:I3Class20comzlbasicJavapTest4Class21javalangObject5Class22comzlbasicJavapTestTest6Utf8Test7Utf8InnerClasses8Utf8count9Utf8I10Utf8init11Utf8()V12Utf8Code13Utf8LineNumberTable14Utf8sum15Utf8(I)I16Utf8SourceFile17Utf8JavapTest。java18NameAndType10:11init:()V19NameAndType8:9count:I20Utf8comzlbasicJavapTest21Utf8javalangObject22Utf8comzlbasicJavapTestTest{publiccom。zl。basic。JavapTest();descriptor:()Vflags:ACCPUBLICCode:stack1,locals1,argssize10:aload01:invokespecial1MethodjavalangObject。init:()V4:returnLineNumberTable:line3:0publicintsum(int);descriptor:(I)Iflags:ACCPUBLICCode:stack3,locals2,argssize20:aload01:dup2:getfield2Fieldcount:I5:iload16:iadd7:putfield2Fieldcount:I10:aload011:getfield2Fieldcount:I14:ireturnLineNumberTable:line8:0line9:10}SourceFile:JavapTest。javaInnerClasses:static65of3;TestclasscomzlbasicJavapTestTestofclasscomzlbasicJavapTest
我们再来逐个字节分析一下,就知道上面内容是怎么来的。用HexEditorNeo打开JavapTest。class。
JavapTest。class
图中的红色数字代表一个项,作为代号我们来逐个分析一下。
1魔数确定这个文件是否为一个能被虚拟机接受的Class文件
2次版本号
3主版本号,34换算10进制为52
4常量池数量,0017换算为10进制为23,常量池计数从1开始,所以共有22个常量
5第一项常量访问标志0a,代表方法引用,0004(4),0012(18)分别指向第4,18个常量
6第二项常量访问标志09代表字段引用,0003(3),0013(19)分别指向第3,19个常量
7第三个常量访问标志07代表类的全限定名0014(20)指向第20个常量
8第四个常量访问标志07代表类的全限定名0014(21)指向第21个常量
9第五个常量访问标志07代表类的全限定名0014(22)指向第22个常量
10第6个常量访问标志01为utf8字符,0004代表有4个字节Test
11第7个常量访问标志01为utf8字符,000c代表后面12个字节是该常量的值InnerClasses
12第8个常量访问标志01为utf8字符,0005代表后面5个字节是该常量的值count
13第9个常量访问标志01为utf8字符,0001代表后面1个字节是该常量的值I
14第10个常量访问标志01为utf8字符,0006代表后面6个字节是该常量的值
15第11个常量访问标志01为utf8字符,0003代表后面3个字节是该常量的值()V
16第12个常量访问标志01为utf8字符,0004代表后面4个字节是该常量的值Code
17第13个常量访问标志01为utf8字符,000f代表后面15个字节是该常量的值LineNumberTable
18第14个常量访问标志01为utf8字符,0003代表后面3个字节是该常量的值sum
19第15个常量访问标志01为utf8字符,0004代表后面4个字节是该常量的值(I)I
20第16个常量访问标志01为utf8字符,000a代表后面10个字节是该常量的值SourceFile
21第17个常量访问标志01为utf8字符,000e代表后面14个字节是该常量的值JavapTest。java
22第18个常量访问标志0c为NameAndType常量,000a(10),000b(11)分别执行第10和11个常量
23第19个常量访问标志01为NameAndType常量,000a(8),000b(9)分别执行第8和9个常量
24第20个常量访问标志01为utf8字符,0016代表后面22个字节是该常量的值comzlbasicJavapTest
25第21个常量访问标志01为utf8字符,0010代表后面16个字节是该常量的值javalangObject
26第22个常量访问标志01为utf8字符,001b代表后面22个字节是该常量的值comzlbasicJavapTestTest
27访问标志0021ACCPUBLIC、ACCSUPER标志为真000100200021
28类索引0003指向第三个常量
29父类索引0004指向第四个常量
30接口索引0000代表没有实现接口
310001代表字段数量1,0002代表private,0008代表字段名称指向常量池的I表示int,0009代表字段描述符指向常量池9即count
方法访问标志说明
320002代表有两个方法,0001代表public,000a指向第十个常量,000b指向第11个常量,0001代表有一个属性,属性名称的索引值为0x000c,对应常量为Code,说明此属性是方法的字节码描述,0000001d(29)代表代码长度,0001是maxstack操作数栈最大深度,0001局部变量表所占的Slot,接下来的四个字节(00000005)是代码长度,字节码长度为5,接下来的5个字节2AB70001B1,接下来0000两个自己表示式异常处理表,这里没有异常所以是0,接着0001属性表示有一个属性,属性索引为000d(13)在常量池中的引用是LineNumberTable。00000006是属性长度,表示后面6字节是它的长度。0001是行号表长度1,包含startpc和linenumber两个u2类型的数据项,前者是字节码行号,后者是Java源码行号(0000:字节码行号,0003:java源码行号)
33。是第二个方法,0001代表public,000e指向第11个常量,000f指向第15个常量,0001代表有一个属性,属性名称的索引值为0x000c,对应常量为Code,0000002b(43)是代码长度,0003,0002分别是栈深度和局部变量表。0000000f(15)字节码长度,2a59b400021b60b500022ab40002ac,0000yi异常处理表,0001有一个属性,000d(13)LineNumberTable,0000000a(10)属性长度,000200000008000a0009(0002行长度为2,0000:0008字节码和源码行号,第二个000a:0009),
方法属性完了继续是内的属性,接下来的0002表示有量个类属性。0010表示指向16号常量SourceFile,00000002是属性长度,0011指向17号常量即JavapTest。java,
0007指向第7个常量池InnerClasses,0000000a(10)属性长度,0001表示内部类数量为1。
0005内部内索引5,0003外部类索引3,内部类名索引指向第6个常量池,0008内部内访问标志是静态标志
至此,JavapTest类的每个字节都分析清楚了,工作中可能用不到这些,但是作为程序员的你一定要知道这个class是怎么组织的很重要。深入理解java是必不可少的。
志愿军为啥可以熟练使用美式枪械?早在开战前就很熟悉2021年9月30日,备受瞩目的抗美援朝题材影片《长津湖》登陆国庆档。这部耗资13亿的战争钜制,将71年前志愿军在长津湖的冰天雪地中痛击美军的艰难战斗和光辉胜利呈现在全国观众眼……
深一度中国女篮存在的意义是什么?听韩旭告诉你2018年女篮世界杯,中国队以88比100负于美国队,这是中国女篮自1983年以来,与美国队交手的最小输球分差。彼时只有18岁的小将韩旭砍下20分和5个篮板,惊艳世界。……
福州人注意!进入这些地方需要72小时核酸证明2022年国庆假期临近,根据当前疫情防控工作要求,为保障广大市民游客生命安全和身体健康,福州鼓岭旅游度假区管委会发布通知。据悉,进入景区的游客请佩戴好口罩,配合做好扫码、……
奥尼尔想执教詹皇?开天价合同4年1亿美金湖人选帅像娱乐节目湖人队炒了主教练弗兰克沃格尔,算是给这个令人倍感失望的赛季一个交代吧。尽管让沃格尔独自担责有些不厚道,但成绩不如预期是不争的事实,主教练被解雇也是惯用的遮丑方式。每个赛季都会有……
狗头军师的由来是什么呢?狗头军师这个词听起来它有很多的戏谑意味。但很多人想不到的是,这样一个极其口语化的词竟然是一个成语。那么既然是成语,必然有它的来历和典故。狗头军师这个成语究竟什么来历?有什么历史……
商朝灭亡后,其族人都跑到哪里去了?商灭亡后,其大部分国人失去了土地,无法从事农业生产,只好做生意去,因此当时做生意的人大部分都是商人,后来就把做生意这个职业称为商人,他们的职业则称为商业。另有一部分商的国……
郭嘉不死卧龙不出,难道诸葛亮那么怕郭嘉吗?对于三国时期的人物,后人多有评价。在曹操阵营中的谋士,有很多人推崇郭嘉。甚至有一些人对照诸葛亮,说出了郭嘉不死卧龙不出的话。似乎是说,如果不是郭嘉早死,诸葛亮就可能不会出世一般……
为什么有大秦,大汉,大唐,大宋,大明,大清,其他王朝没大字?我认为大秦是因为创立大一统之国,开天劈地,前无古人,以此为大,无可厚非。况且秦国本身有500之基。而大汉丶大唐丶大宋丶大明丶大清,都是大一统超过百年以上丶至少二百年到四百……
库里谈维金斯三分手感他的出手非常自信北京时间11月30日,勇士球星斯蒂芬库里在接受采访时谈到了队友维金斯本赛季出色的远投手感。在他加盟球队之前,我们并不知道他是一个多么出色的三分射手,但可以看到他在训练中展……
七年全自研技术这就是零跑汽车的底气零跑汽车坚持自研核心技术:在三电领域,自研一体化电驱总成Heracles以及高性能电池Pack和电控系统;在智能网联领域,搭建LeapCloud系统,实现车端、移动端、云端共联……
足协杯3晋级将战成都蓉城北京时间10月14日,足协杯正赛首轮的比赛继续进行,北京国安迎战四川九牛。第28分钟,王子铭为国安首开纪录,补时阶段,张佳祺头球得手为四川扳平比分;下半场两队均无建树,最终11……
清圣祖康熙清朝历史上最伟大的帝王,同时也是中国封建王朝的有道明君,他就是康熙皇帝爱新觉罗玄烨,8岁登基,14岁亲政,平三藩收台湾三征葛尔丹,奠定了后世中国的版图,同时也为中国人口基数发挥……