[jvm解析系列][六]class里的常量池,访问标志,类的继承关系,如何把一个类在字节码中描述清楚?
Posted 胖子程序员
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[jvm解析系列][六]class里的常量池,访问标志,类的继承关系,如何把一个类在字节码中描述清楚?相关的知识,希望对你有一定的参考价值。
上回我们说到了魔数和版本号,今天我们接着说。为了方便起见,我把那幅图拉过来方便大家看
由图可见接下来是一个叫constant_pool_count翻译过来叫常量池数量,前面我们说到class文件中只有两种数据结构,无符号数和表,而且整篇没有分隔符,在没有分隔符的情况下我们怎么区别数量非1的表的分界线呢。(举个例子:图中的constant_pool,我们想想该怎么标记出constant_pool的结束位置?)没错他的结束位置全都是靠前面的u2类型的constant_pool_count实现的,我打开一个class文件大家看一下。
这里我把43划掉了为什么呢?因为设计者把0空出来了也就说常量池一共有[1,43)个常量所以是42。(只有常量池0空缺,其余都从0开始)
也就是说接下来有42个cp_info表类型的数据结构,那么我们来看一下cp_info怎么构成的。
常量池中我们存什么?字面量和符号引用。
1、字面量,百度百科中这样解释:
其中有几个关键字,源码中,固定值。仔细阅读下来应该跟Java中常量差不多。不过它们的区别在于。字面量一般为右值也就是说int a = 0;这个0就是字面量。
2、符号引用,一般指类和接口的全限定名,字段的名称和描述符,方法的名称和描述符。说白了也就是类和接口的名字以及字段的名字和类型,方法的名字和返回值等能标志出自己的东西。
我们新开一个小一点的类,来仔细看一下它的结构(这个类只实现了一个main方法,很简单的一个类,没有其他变量,静态变量存在,之后解析都是这类)
先上类图:
类的常量池count和常量池:
我们可以看到它的常量池是0x10转化成十进制就是16再去掉0位就是一共15个常量
我们使用javap -verbose xxxx.class来看一下这个class的结构。
我们可以看出来第一列有很多类似于Class,Utf的名称,这个就是cp_info的表结构,这个表结构有一个特殊的地方,就是开始都会有一个u1的标志位。里面一共有11种类型,在jdk1.7后新增了3中暂且不表。着11种类型,这11种类型我们可以分为两种。
1、引用类型:上图中的Class,Methodref,NameAndType以及不在上面的Fieldref和InterfaceMethodref
2、字面量:Utf8,interger float long double string
引用类型的意思是这些类型是引用其他类型的,这样说不好理解我们举个例子,看图#1是class类型他引用了#2,#2是utf8类型代表了Class的限定名。
关于这11个详细的结构网上有很多,我们的class解析是初步解析,以后我可能会加进来,这次暂且不加。其实这一块很简单结合javap完全可以看得懂,相信大家多看看也可以看懂。
那么根据最上面的图,结束了常量池之后就是访问标志。这个类用来形容这个class文件是类还是借口,是public还是abstract,是不是有final修饰符呢。同样的,我们打开一个class文件来看一下
图中所示访问标志位0x0021,那么我们怎么看出来它的信息呢?我送你一张表来看:
请叫我灵魂画师,上面还残留了我输入的框框忘了点掉了。。。。。。
那么根据上图来看我们刚刚剖析的那个类应该占用了public和super两个所以值是0x0021
再根据最上面那个图来看看呢我们接下来应该讲this_class和super_class还有一个不定长的interfaces,关于interfaces这种结构我们在常量池中已经讲过了。其实我们分析到现在,关于一个类的描述也基本完结了(下一节讲方法),除了类的继承关系没讲,那我们就把泪的继承关系讲完来结束掉他吧。
1、this_class顾名思义,其实指向的就是类的全限定名
2、super_class,这个讲的就是弗雷德全限定名了
3、interface,当然就是说接口了。
来来来,我给大家看一下图
00
一不小心少截了一个00,我自己打字补上的,其实thisclass是01,superclass是03,接口没有继承所以count是00。我们看看之前我们的常量值都索引到哪里去了
可以看到01是指向Test类的,03指向Object类跟我们预测的一样,到此我们的类的描述就算讲完了,出了常量池中那11个表结构没有讲,但是我们一般借助javap工具是不需要了解那些表结构的,之后有时间再补上
以上是关于[jvm解析系列][六]class里的常量池,访问标志,类的继承关系,如何把一个类在字节码中描述清楚?的主要内容,如果未能解决你的问题,请参考以下文章
JVM14_Class文件结构细节魔数Class文件版本常量池访问标识(或标志)类索引|父类索引|接口索引集合字段|方法|属性表集合