00:00
上一节啊,咱们花了点时间呢,给大家来讲解一下这个叫常量池,那后边呢,咱们讲中篇字节码文件的时候呢,那就细致的来剖析一下这个常量池的这个细节了,哎,咱们现在呢,还是以讲这个内存结构呢为主要目的呢,咱们去带来一下这个叫常量池啊,带来一下常量池,那么清楚了这个常量池以后呢,咱们下边再来看这个运行时常量池呢,大家就应该比较清楚了,那运行时常量池我们这呢,主要你看我这里边写的文字很多啊,但主要呢,给大家强调呢,其实就是两个问题,首先呢,我们说这个运行式常量池,它是方法区的一部分是吧?然后呢,这个常量池呢,是咱们说自检码文件中的一部分。啊,它主要目的呢,是存放编译器生成的这个各种字变量和符号引用,好那么咱们说呀,就是你自解码文件当中的这个常量池,经过我们类的接载器放到这个方法区以后,这个对应的这个结构呢,就称为这种方法虚线吧,呃,就称为呢叫运行时常量池。运行式常量池,也就是说呢,这个运行式常量池呢,就是咱们资金码文件当中每一个类或者接口啊,对应的这个叫常量池表啊,它的一个表示形式,在运行时候的一个表示形式,说的已经应该已经是非常的直白了。
01:13
这呢是咱们想给大家强调的第一个问题,哎第二个问题呢,就是我这里边想说的一个叫动态性啊,哎,那说这个动态性之前,咱们先把这个,诶上面这个文字咱们再看一看,说呢,运行时常量池在加载类和接口到虚拟机以后呢,就会创建对应的运行时常量池。啊,这个很好理解是吧,就是我们一旦加载以后,每一个类或者接口,它都会对应着一个叫运行式常量值。啊这样子,那它里边维护的信息呢,其实就是我们说到你这里边这个,诶一个呢叫自变量,当然这个时候这个符号引用就不是符号引用了,诶这个你看我们下边写的就转化为对应的这个真实的一个地址了。你不再是指明的具体的说一个string这样一个字符串了啊一个呃这个这个有一个字符串,这个字符串呢,对应的叫string,这有个字符串,这个字串呢叫做system啊这块呢,都是一些自变量的形式是吧,一些符号,那我们真正的在呃运行的时候呢,那我就需要找到真实的那个system那个类了,哎,是这样子的啊,那就转化为这个叫真实的一个地址。
02:12
行,然后看这个说呢,扎va虚金为每一个已加载的类型,或者呃,这个类型是类啊,或者接口酶与类啊,注解啊等等都维护了一个常量池,然后呢,这个当中的数据呢,就像数组一样,用索引来访问啊,这是很直接的,我们这呢,是不是前面都有这个,咱们通过这个井什么来访问这呢,是不是就是这个所谓的这个索引,对吧?啊,那这里边你看一下这个情况啊。咱们在在这呢,写明了说这个叫常量池的一个count是85是吧,那我们看这块呢,是从零一啊一直往下拽啊,这是不是到84啊,哎,这要注意就是咱们整个这个索引呢,个数的话呢,是从一到这个抗减一。啊,这要注意一下哎,从一到C减一,实际上呢,也就是说这个个数呢,比我们这里边写的这个size是不是要小一,哎,这个C减一就是我们所谓的这个,哎。这个最后的一个索引啊,诶24行我们这有索引,大家呢,通过这个索引呢,去呃调用就行啊,像我们下边的这些扣的代码,凡是用那个井什么的,这个后边呢,是不是都是对应的咱们常量池的这个索引,对吧?诶去常量池里边去用就行,诶这个大家你看这个代码,你就想着你炒菜呢。
03:17
啊,你炒菜呢啊,这是咱们那会儿是不是找这个字符串,这个字符串是在这儿呢,是吧,这个15。你看这呢,是咱们说这个字串,嗯行就是嗯,你你就假想假假想呢,你是在炒菜,那你炒菜的过程当中,就是我们的一个一个方法的一个调用过程,那你这里边呢,需要的任何的一些结构,其实我们都是可以考虑来这个常量池里边去找这个相关的一些配料的。那这呢,就是我们所谓的这个叫哎常量值。啊就这样的行,那么你这里边记住呢,比如说你想需要味精,那你在这个编译的时候呢,那个味精它只是一个描述,就叫做这个味精,当然现在咱们说不让用这个味精了,是吧?说这个是一个化工产品不太好哈,诶这个你就诶标识这个叫味精。
04:02
这呢只是一个叫符号引用,那么真正在我们执行的时候呢,那你就得是真正炒菜了,那你得真的是把这个威尔精是不是得放进去啊,哎,那就是一个直接引用了。啊,如果没有还需要呢,去加载,那就该加载还加载啊这样行。这呢是通过这个索引来访问啊。嗯,这个然后呢,说运行时场景中包含多种不同的常量,有这个数值的,这个自变量,呃,也包括呢,这个到运行期啊,呃,到这个运行期解析以后呢,才能获得这个方法和字段这个引用,哎,就把这个符号引用转化为这个叫真实地址的,哎刚才已经说过了,那下边又说了一个,说这个运行式常量池啊,它相较于咱们class文件,这个常量池的另一个重要特征就是动态性。哎,刚才说给大家讲两个点,一个点呢就是这个啊,一个点呢,就是我们说的这个叫动态性,什么意思啊,就是我们这个运行时常量池当中,它没画的有点大了哈,它当中不光能够放是我们这个自解码文件中的这个常量池的这个信息放过来,它有可能还会更多一些,它有个动态性,比如说呢,嗯,比如说谁啊,咱们讲这个啊,这个我写到写到这儿也行啊,举一个例子,咱们这个string的话呢,它有一个方法啊,或者直接我们就来调啊,是不,这个方法呢,叫做in的方法。
05:14
这个验证方法的话呢,我们就考虑呢,是不是把你这个string如果呢,在常量池当中没有,是不是我们要放一个这个诶常量呢,到我们这个常量池当中啊,诶所以这呢就体现了在代码层面呢,还有一个动态性,就是它呢运用式常量池中放的内容呢,是不是比我们这个常量池里边的信息呢,有可能是要更多一些,是吧,有了这种动态的特性啊。行啊,那如果说呢,你这个运行时常量池,呃,它这相较于我们传统这个符号表,它是有一定的呃相似度啊,这个了解一下就可以了,然后呢,这个创建类或者接口的运行式常量值超出了这个方法呢,所能承受的最大值,这个呢就抛出这个OM啊,这个不用多说了,行,那么运行式常量池这两个点说清楚就可以了。啊,那么至此的话呢,咱们把这个方法区的这个内部结构,哎,就算是给咱呢介绍清楚了。
06:03
诶大家呢,能够去做一个理解啊,能够做一个理解,整体上来讲呢,我们说包含这几个部分,但是你注意啊,这个后续呢,还会有一些演变,这个演变的话呢,在咱们讲完这个方法去使用举例之后呢,啊,这能放了很多图哈,给大家去讲一下这个具体这个演变细节,这里边会涉及到呢,关于这个字符串常量值和看静态变量它的一个变化。啊,这个大家稍微关注一下啊,咱们上面讲的这个呢,是一个相对来说比较经典的一个方法去存储内容啊,这样的一些信息啊。
我来说两句