00:00
那下边咱们来看一下这个环节三叫做链接阶段的解析环节啊解析啊resolution解析什么呢?呃,主要呢,是我们将啊类接口啊,包括呢,我们类接口中的像这个字段方法,它们对应的这个符号引用转化为对应的叫直接引用。啊,这个符号引用直接引用伴随着咱们整个讲解这个词解码,包括内存解析的这个整体的环节,对吧,符号引用的话呢,我们知道在这个。对应的一个,呃,Java类中的自解码文件里边啊,就比如咱们这个类,咱们看着它这个对应的结构,呃,有一个叫常量池对吧,那常量池里边我们说保存的就是一些字面量和符号引用啊,比如说我们这里边引用的谁呢?是com艾特硅谷Java下的叫in test啊是这样一个类,那这呢是我们引用的这个类的信息,然后这个类的话呢,它又指向了一个对应的一个是不是字符串的一个自变量,对吧。哎,就是这样一个字符串,然后除了这之外呢,我们还有引用了像Java浪包下这个object债这个类啊,这个类的话呢,也指向了一个呃,对应的24这是一个呃字符串的一个常量了,是吧,或者叫自变量,那像这呢,Class这呢,都是我们说的叫类型信息,那我们也有对应的像关于一些属性的信息啊,对吧,关于方法的信息啊,这个准确的来讲,我们主要是看下边这块了,那下边这块有属性有方法对吧。
01:21
那比如说像方法这块啊,我这块可以再写一个例子,像比如public返回值呢,是一个object类型啊叫get OB接,哎,我们暂时呢先return一个now行,把这个呢,我们重新做一个编译。那这块的话呢,我们做一个刷新,好,那这时候呢,我们方法呢,就有一个叫get obj,那这个方法的话呢,我们看到它的一个,那方法的名字呢,叫get OB阶,那引用的就是咱们常量池里边的这样的一个,相当于就是一个自变量啊,就20啊这是一个自变量,然后关于这个方法的话呢,描述符这块呢,就提到了它的一个,呃,叫什么反问类型。
02:01
啊l Java long object,像这个呢,我们看到其实就是算一个四变量啊,指向呢,就是咱们常量池里边这个21,哎,指向到这了是吧?哎,到这说明的是一个它,那真正的我们这个要把当前你这个类叫另一个test,这个类加载到内存中之后呢,我们这里边像出现的比如说你这个object呀,相对应的是不是也得需要做个加载,那你得告诉我真正的这个类它的一个地址值是多少。哎,包括呢,我们说当前这个类中的方法,像我们这儿呢,是不是就只有,呃,这有一个方法,这个呢,是咱们编译器帮咱们生成的方法啊,那咱们换一个,比如说刚才提到的这个这个类里边的话呢,我们就定义了很多的方法,对吧。哎,这个说一下,这呢,我们就定义了很多的这个方法,那这个方法呢,整体上它其实就相当于构成了一个方法表这样的一个集合,那这个集合当中呢,呃,你这边也有对应的一个一个的方法,我们上面呢,是不是也有很多这个关于方法名的一些描述信息,这个咱们得去找了啊,呃,关于方法名的这样的一些描述信息,看能找着不?那比如这个if,呃,这个这个好像还不是这是类的一个描述,对吧?像这个COMPARE1,这不就我们关于这个COMPARE1这个方法名了一个描述嘛,然后真正我们在。
03:14
解析的这个环节中呢,你需要把这个方法呢,对应的内存中真实的那个地址,你得告诉我,那你得告诉我那个地址,然后我们要调的话呢,得找到你那个地址,那这个过程呢,我们就称为呢,叫将符号引用转化为这个直接引用的这个过程。也不知道大家是不是有点晕,没有啊啊,不知道有没有晕啊,就好比是呢,咱们平时说我现在呢想去北京天安门,然后这块呢,就告诉你,你呢先坐这一趟车啊,到哪一站下,然后再坐哪一趟车到哪一站下,然后再呢骑个自行车啊,比如到这个天安门广场了,然后呢这呢就相当于是叫什么呀,符号引用。然后真正当你去的时候呢,说比如说先做一个叫比如说这个八号线,嗯,八号线到哪块下,然后再转成比如说13号线过去,那真正你过去的时候呢,你是不是就得找到真实的那个八号线啊,那个地铁对吧,然后13号线那个地铁,然后真实的那就是我们实际你去操作的时候呢,那个真实的内存的地址了,就相当于叫直接引用,哎符号引用呢,就是我们面上说的这样的一个过程,哎这个注意,那再换一个例子呢,就好比是大家呢,这个不知道,呃,都在家做不做饭啊,这个在家做饭的话呢,我们有时候你不清楚,你得看个菜谱吧,那菜谱当中说你第一步干这个啊,第二步,第一步就是把这个菜洗干净啊,放一些这个佐料到锅里边,然后热了之后呢,把这个菜什么先放进去再怎么着,整个这个环节当中,其实涉及到这些呢,都可以理解成叫符号引用。
04:38
当你真正去做菜的时候,那我们现在也是加载的过程,真正也开始加载了,这就真正开始做这个菜了,有真正的内内存了啊也有你这个看,就相当于有你看得见摸得着的这些蔬菜和原材料了,那你这块呢,就是真正去操作的时候呢,都是这个直接引用说呢,你你把这个第三个,比如说我们这放了一排菜是吧?呃,先放什么,后放什么,再放什么,就有一个表说呢,你把这个第三个这个原材料放到这个锅里边,然后再把第四个原材料倒进去啊,第三个第四个哎,往这一看啊,第三个就是白菜倒进去。
05:09
啊,第四个呢,是把这个盐呢倒进去,白菜盐,那你这块呢,真实的找到这个地址啊,然后把它倒进去,那这块就是我们说的这个真实的,你说第三个位置,那就是这个符号引用里边,你说的三真实在哪呢?就是看这个桌面上的那个,呃,内存地址,第三位那个你看0X是多少多少多少啊,那就是直接引用了。哎,就这个意思啊行,那下边呢,这块又举了一个方法啊,这个方法呢,就是一个printline这样一个方法。那这个方法呢,咱们回过来举个例子啊,举个例子,就比如说咱们在这里边儿呢,咱可以再去写一个啊,简单的一个操作啊,假设呢,我们这儿方法呢,叫PRINT1,在这里边我们就写一个输出语句,比如句叫做hello。把它呢做一个编译。嗯,那这块呢,我们再做一个这个,呃,刷新好,那我们来看一下这个方法叫。
06:05
哎,看错了,嗯,找这个。刷新一下。叫这个PRINT1,然后这个方法的话呢,我们在这里边code里边呢,就是我们叫通过in,呃,这个invo virtual去调用一下我们这个print stream里边这个叫这个方法。嗯,这块调用的呢,就是我们这个景四,那相应的就是我们这个里边的是不是这个方法了,对吧,那这关于这个方法的描述的描述的话呢,我们说有两部分,第一个呢,就是你这个方法,你所属的这个类是哪,那这块呢,就提到一个类型的信息,那相应的这个类呢,这不就需要得去加载,那那暂时呢,你告诉我是32这个位置。哎,32这个位置是吧,这是一个class,那现在呢,我们需要真正在内存中,如果要执行的话呢,你是不是需要呢,把这个真实的你内存中的这个类的这个地址你得告诉我呀。对吧,哎,真实这个内存中这个地址你得告诉我,然后的话呢,我们关于这方法名叫print LA啊叫LA,然后这个tap呢,就是涉及到它的这个描述符,嗯,是一个有返回值是string类型,反嗯,Print这块呢,是提到有返问类型,我们调的是这个参数呢,是string的这样的一个参数的方法,对吧,那返回值呢,这块是Y。
07:21
行三呢是14缀啊,行三是四缀,然后这呢,就是它这个描述符,那么通过这个方法名,我们还确定不了某一个方法可能重载嘛,但是再结合着它这个形态列表,那我们这块呢,就唯一确定了这个方法了,那这时候你得告诉我在print stream这个真实的内存中,这个类当中,这个方法呢?呃,这个类中可能有很多的方法,对吧?有个方法表一个一个的排了很多,你得告诉我这个方法到底是在第几个位置上。啊,你得告诉我真实的那个内存地址了,就不能是简单的光告诉我是井33这样的一个,呃,关于方法的一个描述的信息了。哎,这呢,就是要转化成真实的一个内存中的那个相应的偏移量。
08:03
哎,这个大家关注一下这个问题啊,这个是咱们反复的来说这个符号引用和直接引用,就怕大家呢这块迷糊啊,哎,你看这里边提到的说以方法为例呢,Java虚拟机会为每个类呢准备一个方法表啊,就比如说咱们这个print stream这个类中啊,有很多的这个方法,那print line参数呢啊,我这写的是个int类型的啊,比如说你打印个123,哎,是这个类型的word的,它只是其中的某一个确定的方法。这个所有的这个类中的方法呢,都列在这个表当中,当我们要调某一个方法的时候呢,你得需要告诉我这个方法在这个表中的哪个具体的位置啊,那就相当于我们这个直接引用这个位置,通过解析操作呢,符号引用就转化成对应的这个表中的这个位置的,那就是一个直接引用,我们就可以进行一个调用。哎,就是这个场景啊,就是这个场景那行了,然后这个呢,小结呢,就提到了,说解析这个环节呢,就是符号引用转换成直接引用,那如果说呢,我们在一个类当中有一个直接引用的存在。
09:01
啊,有一个直接应用存在,那显然呢,内存中是不是一定加载了相关的这个结构吧。我们都找到这个真实的内存中的这个地址了,那肯定是加载了对吧,但是呢,你要是只有for呢,那不一定能找到这个结构,那要找不到的话呢,这块是不是又在我们这个环节就报错了。哎,通过符号引用找这引用没找到,那不是解析环节就搞错了嘛,对吧?哎,是这个情况啊。下一个这个点呢,咱们想强调的问题是什么呢?就是咱们现在呢,提到了叫加载验证准备解析,嗯,还有初始化对吧,整个呢这块呢,大方向上是按照这个顺序来执行的啊,但是我们也提到过这个验证的话呢,通常是跟这个加载呢,是不是同时来执行。也就是在加载的过程当中,我们就进行了验证了,另外呢,我们还提到这个解析的环节,把符号引用呢,转化成直接引用,通常呢,它是在我们这个诶初始化这个环节之后来进行的。初始化这个环节呢,就涉及到咱们在准备这个环节去做的默认初始化值赋值对吧,那初始化环节呢,就涉及到显示赋值的问题。
10:03
啊,一般显示赋值的这个之后我们才进行一个解析,但是这里边儿我们还是统称为呢,叫链接这个环节。哎,叫链接这个环节啊,这个大家注意一下这个事儿,嗯,然后再下面是关于这个字符串的一个描述,大家会看到咱们这个常量池当中是不是出现大量的这个叫UTF8的这个音符是吧,那其实对应的是不是都是字符串信息吧,对吧?那当然这个呢,我们还会出现一个专门string的个音符,这个针对的呢,是咱们当前这个类当中,如果出现这个string类型的叫常量的话,哎,全局常量的话呢,我们就会生成这个叫string,这个in for。嗯,然后呢,它也会指向你对应的你声这个声明的这个自变量的这个值是多少,像这呢是36。啊,也是一个字符串对吧,那这呢,就提到这个UTF8,这个UTF8呢,我们在保存的时候,当然你会发现,凡是呢,你不管是类的名字也好,还是方法名啊,属性名也好,还是我们这个相应字符串的这个对应的真实的这个值也好,只要呢,你哎两个字符串这个值的信息一样。
11:05
那我们这块呢,都会对应的是同一个,哎,常量池中的这个名字。这个字符串名字,那也就意味着咱们在上面中也提到过,咱们呢会有一个专门的结构叫做字符串常量池啊,咱们在这呢,也可以把它翻译成呢,叫做一个呃字符串的一个居流表,就int方法,那我们调离int方法的时候呢,就会从这个字符串常量池里边去确定某一个呃常量呢,看存不存在,不存在呢,我们就创建一个,那存在的话呢,我们就用这个线程的,对吧?那我们这个常量字符串常量池里边是不会存在这个重复项的,这个咱们在讲上篇的时候呢,专门拿了一张来讲这个字物串,哎这块呢就不用多说了。好,那这里呢,咱们重点呢,大家需要记住的就是解析的这句话。好这呢,就整个呢,是咱们说的这个叫呃,链接的这样一个阶段的三个环节。
我来说两句