00:00
那常量池计数器输完之后呢,我们现在就进入这个重点的叫做常量池表,哎,常量池表里边到底存了多少条这个常量数据呢?呃,就是我们常量值计数器减一就可以了,所以呢,就是从一开始到呃,常量值计数器减一这样的一个范围啊,这呢就是作为这个索引出现的,那常量值表里边我们刚才也提到了它存放的两类数据啊,一类呢就是叫自变量,一类呢叫做符号引用,这呢提到叫主要的两类数据。啊怎么讲呢,就是我们下边呢,就是我们能放的这个数据啊呃,这个自变量的话呢,就是我们常见的比如说基本数类型啊,包括这个字串这个类型的这个常量啊是吧?诶都称为呢叫字变量,那我们也可以呢,去保存咱们关于类当中方法属性的这个,哎,叫属性,其实应该叫字段了啊的符号引用,包括接口中的这个字段和方法的这个符号引用等等啊这呢都称为叫符号引用,哎主要放的是这两类结构,在这这个七的时候呢,我们又引入了三个新的结构。就是对应的这三个来体现呢,Java对这个动态语言的一个支持啊,这个大家稍微关注一下就可以了啊来主要呢,咱们放的还是上边这样的一些字面量和符号引用啊,是这样子的啊,那么类型这块啊,大家也刚才看到了啊,这是什么意思呢?哎,是这个意思啊,刚才呢,咱们不是说这个计数器的时候提到了一个数组嘛,是吧,这个数组比如我这样来定义的,大家就知道呢,我们整个数组元素呢,是有十个,每一个元素的类型呢,都是int类型。
01:29
对吧,你看都是int类型啊,但是咱们对于这个常量池表啊,实际上也可以看成是就咱们讲的这个数组啊,它里边存放的这个元素啊,可能是下边当中的任何一个,也就是说可能我们第一个角标为一的位置啊,咱放的是一个诶浮点类型的自变量,然后第二个位置呢,我放的就是这个,诶class in盒了,第三个呢,我放的是它,第四个呢放是它啊,第五个放的是它。那第六个放的还是这个类型的又一个,哎,就是这样意思,就是表中元素的类型可能是下边这一共是有16个中的任何一个。
02:05
啊,任何一个,那就是相当于就是我们打开一下这个最起码文件的话呢,就是接下来呢,你看到的这个,呃,常量池当中啊,这个咱们不是说已经表示的长度了,在后边开始是不是就表示我们具体的这个常量了,那到底是哪一个呢?哎,这个0a 0A对应的是十,那是啥呀?哎,这个十呢,我们回过来一看,哦,叫method reference是吧,In,哎,相当于就通过这个标识,咱们就知道你第一项啊放的是它。哎,这个注意啊,就是这样的一个概念。好,哎,那这呢,我们对这个常量池里边这个能存放的信息是吧,这个信息的话呢,到底是哪一个呢?诶我们提到了一个叫标识的一个概念,这个标识呢,用英文呢,叫做tag啊,叫做tag啊好,那自变量符号引用咱们再进一步呢,进行一个解释。哎,再进一步进行一个解释,自变量的话呢,这里边儿主要提到有两种情况,一个呢叫做本本字无创。哎,叫做文本字符串啊,就好比是呢,比如我们在乘以当中啊,定义一个这个string st2啊,咱们写一个叫艾特硅谷是吧,哎,这样的一个字符串。
03:09
还要把它稍微变大一点。那么这个字符串呢,其实就相当于是一个字符串的一个自变量了,它呢,哎,就放在我们这个字符串,呃,就放在我们这个常量池当中,哎,它这时候呢,其实就是一个叫自变量啊,还有一种情况呢,叫生命为final的常量值。啊,声明final,比如我们定义一个final类型int的number,这个值呢是十,那么这个十呢,哎,也看作是一个字面量。啊,十也好,爱的硅谷也好,都存放在咱们这个常量池当中是吧,准确的说叫常量池表当中。这时候跟内存还没有关系啊,大家注意,这时候我们这个数据呢,是在这个资金码文件中,或者是一个二进制流是吧?呃,它不是一个内存中的一个,呃,真实的数据啊,现在还没有存放到内存里呢,然后下一个概念呢,我们提到了叫做符号引用。这个符号引用呢,大家不知道还记不记得,咱们在前边讲这个上篇的时候,呃,咱们在讲这个上篇的时候呢,讲到这个,呃,内存中的这个,呃加载过程啊,提到过类的加载,然后这个链接呃初始化,然后在这个链接过程当中,我们其实讲到过这个符号引用。
04:18
是吧,诶,符号引用啊,直接引用啊,咱们讲到过这个概念啊,只不过当时呢,大家理解呢,其实并不太好,很多同学呢,感觉很懵啊啊,那咱们当时也说过啊,要想大家对这个符号引用有更深刻的理解啊,看得见摸得着是吧?哎,那我们得需要去解析这个随解码文件啊,下面就是咱们解析这个随解码文件这个过程啊,那符号营呢,主要呢,是有这样的三种情况啊,比如说我们类或者接口的这个权限的名。啊,然后呢,字段就我们说的field的名称,描述符描述符,就比如说你的这个字段的类型,那方法的名称啊和描述符,描述符,比如说你的反类型。行参是吧,哎这块呢,哎都是对应的,我们这个叫描述符,这些呢,我们都理解成了叫符号引用啊,那么关于这个符号引用,哎这块咱们下边呢,再来看一下啊呃,首先呢,这块提到叫权限类名啊,这个大家稍微注意一下,咱们以前呢,写JA号程序的时候呢,提到过叫权类名是吧?哎,全类名当然我们写的话呢,是用一个点来表示的啊,比如说咱们哎这里边这个DEMO,那这个DEMO的全这个类名的话呢。
05:25
其实就是就他嘛,哎,我们说叫全类名啊。哎,他的权利名称叫com点艾特硅谷点JAVA1,诶下的这个叫DEMO。这呢是它的这个权类名是吧,那现在呢,我们提到一个叫提到一个叫什么权限定名,这个权限定名呢,诶注意你把这个点呢,改成是这个斜杠啊,哎哎,这硅骨下的哎叫扎瓦一下的哎叫DEMO是吧。哎,这样个情况啊,这呢就是我们称为呢,叫做权哎限定名。OK,那这个权限列名的话呢,呃,为了我们跟后边这个其他的这个结构呢,不产生这个混淆,我们可以以一个分号呢来结束。
06:07
啊,就是加一个分号结束啊这就可以了啊行,接着往后说,嗯,这个字段,呃或者是这个方法,这个我们提到这个名称啊,这个名称呢,我们称为呢叫简单名称,比如说呢,咱们在这个成语当中提到这个叫爱的方法number的这个字段啊,这个number nu和这个ad啊这呢就相当于是这个叫名称。哎,这呢就叫做名称是吧,然后下边这个描述符,刚才提到了字段的类型,方法的这个参数列表,还有这个返回值是吧?哎,这个呢,都算是叫描述符,那描述符这块呢,我们需要刻画一下,因为提到了类型啊,对不对啊,那么类型的话呢,不管是字段也好,还是我们这个方法的行三也好,对吧?哎,那么类型呢,逃不出我们这个表。啊,咱们在讲这个Java的时候呢,其实也都强调过啊,咱们把这个呃,Java中的这个数据类型啊,分成了叫基本数据类型啊primitive是吧,数据类型还有呢,叫做引用数据类型啊reference。
07:08
哎,这样的两种类型大体上是这样分类的啊,那么基本数据类型呢,我们说又有八种啊,然后营数据类型呢,也有这个,呃,数组啊,这个类呀,包括这个接口啊是吧,都算啊OK,那我们把这个呢,具体的每一个都做一个表示啊,就是我们下边这样的一个表格。啊,基本数据类型呢,如果是叫bad呢,我们就用这个大B来表示叉类型C啊,大部型用d float型用F啊,Int型用I,这个这呢都还比较好说是吧,包括这个哨的类型啊,那剩下这块呢,大家关注一下啊,Long类型这个我们没有用L啊,因为这个L呢,我们是占用了,拿这个引用类型来进行占用了啊,准确的说呢,是这个对象啊占用了啊用L了,所以这块long呢,我们用的是这个勾啊,或者叫接也行啊。布尔类型呢,我们用的是这个Z啊,因为B的话呢,被这个BY占用了,OK,然后这个Y的话呢,其实我们也看作是一种类型了啊,是用这个大V来表示的,呃,数组呢,我们在只要是一位数组就是一个它啊两位数组呢就是这样,三位数组就用这个来表示了。
08:12
那这个大家稍微关注一下哈,行,那么这呢,就是来刻画咱们这个呃,字段也好,还是方法的这个形态也好,它的这个具体类型的啊,这样的一些标志符,那这个大家呢,需要关注一下啊,需要关注一下,那关于数组这块呢,大家平时可能接触的稍微少一点啊,这咱可以给大家稍微举一个例子啊,比如我们在这个障碍一线呢,稍微写这样的一个代码。啊啊。好,整一个没方法。嗯,比如我们定一个叫object类型的一个数组啊,这个是AR。哎,长度呢,比如说就是十。哎,我们打印一下。嗯,这个AR啊啊,接着我们再定一个,比如说词string类型的一个数组。
09:03
好哎,再来一个,比如说浪类型的,基本属于类型啊,浪类型的二维数组。OK行,那这时候呢,咱们打印一下,看看这个具体的一个效果啊,这个我们是二位数组嘛,再补一个执行。那么我们知道呢,对于引用数据类型的变量,默认情况下呢,它打印的就是你当前这个对象的一个地址是吧?啊以及呢,它的类型,那我们看一下这个类型,这个第一个啊,咱们打印出来是这样一个数据。嗯,那现在呢,大家就知道为什么长这样子了啊,首先呢,表明这呢,就是我们刚才提到了一个叫权限的名对吧,然后权限的名后边呢,我们以一个分号来来结束,然后呢,呃,前面呢,LL呢就表达的是咱们刚才说的是这种对象类型的啊,所以是一个L。啊,那又因为呢,你是一个数组嘛,一维的是吧,哎,所以一维数组,然后呢,类型呢,是一个引用类型的啊,对象类型的啊object这个情况啊,加个分号,现在呢,就能知道为什么是这个意思了,对吧。
10:05
好,这个词类呢也类似啊,就不多说了,那针对我针对我们这个浪类型呢,我们说呢,你是一个二维数组,所以呢,你看有两个中括号,然后其次的话呢,浪类型咱们呢,用的是这个勾来表示的。哎,用它来表示对吧,哎,所以这块我们打印的效果呢,就是长这样子的基本数据类型这块,注意就不要加这个分号了啊,只有呢,我们这个引用数据类型啊,这个权限的名这块呢,我们才有这个分号。OK是吧,哎这呢大家就能理解了啊行,这呢就是咱们哎说到的这个关于这个字面量啊,还有这个符号引用啊,这样的一个概念啊,这个大家要清楚。然后下边这块有一个补充的内容啊,补充的内容看大家这块呢,能不能还理解我们这里边这个事儿啊。嗯,补充内容是说这个说虚拟机啊,在加载class文件的时候呢,才会进行动态链接,实际上这块内容咱们在前面讲上边的类的加载时候提到过啊,呃,当然有的同学可能呃当时比较懵啊,那咱们接下来基于这个符号引用呢,我们看看这个事儿啊,加载plus文件的时候呢,才会进行动态的链接,嗯,什么意思呢?哎,因为只要提到这个动态链接啊,哎,已经涉及到这个内存,就是真正这个运行了啊,你看加载了嘛,一旦涉及到加载了,这就涉及到我们这个程序呢,要执行那个java.ex这个命令了哈,那这块呢,咱们看一下咱们讲上天的时候呢,画的相关的一些图啊。
11:31
嗯,上篇。上面呢,我们首先看一下是这个图,在这个站里边啊,我们说有这样的一些结构,其中有一部分呢,我们就称为呢叫动态链接,就指向运行时常链中的这个结构啊,简称呢叫动态链接了啊,那我们再来看一下这个图。哎,再来看一下这个图啊,或者这个准确的说应该是下一个这个图是吧,这个图哈,呃,我们在这个占空间,你看占空间也好,还是你这个堆空间也好,这是不是已经涉及到我们这个运行的这个过程啊。
12:02
啊,已经使用类的加载器啊,已经执行了java.ex这个命令了啊,那么我们的常量池加载到内存中之后呢,它放在叫运行时常量池当中。啊,这个时候呢,是已经变成对应的一些直接引用了,有真正的内存地址的,诶,我们有这个动态链接,然后指向啊,你真正的要操作的那个方法啊,那样的一个常量是吧?哎,就这样的一个过程啊,这的称为呢叫动态链接啊。呃,这个动态链接呢,只有在加载class文件之后呢,咱们才会出现啊,也就是说。Class文件当中啊,它不会保存各个方法或者是字段的最终内存的布局信息。这个是一定非常大家要明确的啊呃,自检码文件当中是不包含内存中的这个情况的,因为还没有加载到内存当中对吧?呃,当虚拟机运行的时候,我们需要呢,从常量池当中获得对应的符号引用,哎,常量池当中拿到符号引用,然后呢,在它加载之后,我们就能够替换为直接引用了,哎,我就真正知道你这个,哎,相应的这些数据是吧,相应的这数据在内存中存放在哪个位置了,我们就能得到真实的内存地址,然后呢,我们就可以实现啊,你相关的一些方法和结构的一个调用了。
13:18
哎,这呢,我们称为呢叫动态链接啊,称为呢是符号引用啊,转换为对应的这个直接引用,这个过程呢,就是我们执行了一个java.exe命令啊,加载class文件中啊,准确的说呢,是在这个呃,解析的这个环节实现的是吧。啊,这也属于我们链接步骤中一个嘛,记得吧。哎,这个找一下这个图。呃,整个我们的这个加载过程,嗯,咱们看下这是吧,哎,这个链接过程呢,分成验证准备和解析啊,刚才说的就是这个解析的过程啊。那再来描述一下这个符号引用呢,就是一组符号啊,就是一组符号什么呢?就是咱们刚才提到这些东西。
14:00
啊,或者大家觉得还是不够形象,因为咱们毕竟现在还没有开始是不是剖析下边这些信息了是吧?哎,那你可以看一下我们使用这个工具帮咱们解析好的啊,哎,你看这不就是具体的一些符号信息吗?刚刚才提到了,比如说关于你这个,哎,咱们往下看看啊,哎,关于你这个呃,方法的描述符啊,反回值类型这块啊是V,然后呢,形态没有是吧?哎,这是属性了啊,这个咱们先过掉,呃,这个关于你当前这个类的一个描述啊,L这个属于对象类型的最后一个分号结尾对吧。这个呢,是不是我们说的方法名啊啊,这个呢是关于一个还是方法的一个描述符,呃,返回的是一个int类型,然后没有参数对吧?像这些呢,咱们都看作这叫符号引用啊,真正的你加载到内存中之后呢,我们有这个艾的方法了,哎,就相当于是一个直接引用了啊,因为有真实的这个内存的这个地址了嘛。对吧,哎,符号引用呢,跟我们内存布局是不相关的,而直接引用呢,哎,它。这个已经加到内存中了,它跟这个内存布局呢,就息息相关啊,可以看作是呢,直接指向目标的一个指针啊,一个相对偏移量,或者是一个能间接定位到目标的一个句柄啊,都算是叫直接引用。
15:13
啊,就是真实看得见摸得着的,哎,内存当中的。哎,这部分结构了,这叫运行时常量之之中的这个叫直接引用啊,就这样一个概念啊,行,那解释到这儿的话呢,不知道大家是不是彻底的对这个符号引用和直接引用啊,有一个比较清晰的一个认识,如果感觉还差点意思啊,那咱们下边呢,就开始真正的来讲解这里边的哎,符号引用了。啊,那加载到内存中的那个就叫直接引用啊,在解析环节加载的那下边呢,我们就看一下,呃,具体的这个在常量尺中的这些结构了啊,咱们来进行一个剖析。
我来说两句