00:00
那关于扎P这个核心的这几个参数呢,咱们就说到这儿,重点呢,大家需要掌握的就是杠V和杠P这两个指令,包括呢,我们这有提到了,这三个指令的一个区别在哪里?好,那下边呢,咱们就举个例子,这个例子的话呢,其实也是咱们刚才在代码当中,诶反复呢去使用的扎p test的这样的一个例子,通过这个例子的话呢,咱们剖析一下,跟咱们前面咱自己一个一个词解码解读,嗯,以及呢,咱们跟这个。这个j lab我们对比一下,看看里边有没有一些细微的一些区别啊,这块咱们说一下行,那这块解读的话呢,咱们生成的这个自解码文件呢,咱们刚才那会儿已经是不是放到我们这个二的这个扎p test的这个自建码文件里了,对吧?那针对它呢,咱们给他呢这个CMD。这样做一个相对重要的完整参数的这样的一个使用,嗯,就是当RP,咱们一个提到叫杠V,就是包括了我们这个信息呢比较全,杠P呢,就是把私有以上的这个结构,权限的这个结构呢都包含在内,然后后边呢,我们写一下张p test点自解码文件,然后呢,我们把这个数据呢写出到这块呢,我们写一个。
01:09
就叫p test吧,这样的一个T文件里边能看懂对吧?好,我们回车一下。那这时候呢,就给我们生成一个JP t.T文件,把这个T文件呢打开,这样呢,就相当于我们使用这个JP指令啊,也使用了它最重要的杠V和杠P这两个指令得到的一个解析反解析,或者叫一个反反反编译也行,生成的这样的一个文件,这个文件呢,咱们跟用这个JR lab做一个简单的一个比较,那咱们主要呢,先来看一下这个时候的这个生成的JP指令,生成这个文件里边都包含了哪些基本的信息。首先呢,叫class file,就是我们当前这个自解码文件的一个所属的路径,这个呢,就是我们刚才那会提到是不是c infer里边这个信息,对吧,这个我们称为呢,叫字解码文件所属的这个路径啊,这个是OK的,然后下边。
02:05
嗯,这个我就空格一下吧。下面这个的话叫last modified,就是最后的修改时间。修改时间包括呢,我们说这个字解码这个文件的大小,嗯,这个呢,是不是都比较清楚,OK,这个是1358字节,那其实就相当于是我们这个字节码文件呢,我们看下它的属性,这不就1358字节嘛,就这意思,包括在这儿呢,其实也能看到它这个修改,最后这个修改的这个时间,对吧?OK,行,那我们再回过来。然后MD5这呢,就是我们说MD5的这个散列值。嗯,这个散列是OK,这个呢,我们就放这就行,然后下面的话呢,其实就指明了我们comp from当前这个字节码文件呢,是哪一个原文件给它编译得到的,对吧,相当于指明了我们原文件的名字啊名称,然后再往下呢,就是当前我们这个类的一个呃,权利名了啊,Com点爱圭五点障碍一下的这样的一个类行,然后再往后这个信息的话呢,咱们前面讲这个资金码的时候呢,专门说过叫minor version,这个称为呢叫小版本,或者你称为呢叫副版本也可以。
03:23
然后下边呢叫major version,这个呢,我们称为它叫主版本。那这两个话呢,共同构成了,就是咱们在这个一开始讲class文件结构当中,是不是提到这个叫。Class文件的一个版本号对吧?啊,这个我们说过,那这里边对应的我们叫52.0,其实就是咱们JDK8啊这个都清楚,下边这个flax呢,实际上呢,它指明的是咱们的这个信息。是不是访问标识啊,嗯,Access flag对吧,访问标识。这个呢,是咱们当前这个类的一个访问标识,嗯,ACC啊杠super这个呢,指明就是咱们当前是一个类,只要是个类的话呢,都有这样的一个标识了,然后在前边这个public就指定当前这个类的一个权限修饰符是public的,OK,这个呢比较清楚,在下边呢,是不是就我们所谓的常量池的信息啊,也是我们说自金码文件当中最为重要的一个结构。
04:18
这是常量池的一个情况,这个呢不用多说吧,跟咱们前面自己解读也好,包括呢我们使用这个。接开lab也好,是不是都能看到这个常量池的这个结构,对吧,那这是我们通过这个接lab来看的,然后这块呢,是我们使用的。嗯,是用的是这个加P来看的啊,这是一样的,行,这个就过了,然后再往后这块,从这块儿开始起,下边这个大括号里边,大家首先看到的这些,嗯,先到这儿吧。诶不是先不是先到这儿,应该是先到这儿对吧,那么这些呢,是不是都是咱们所谓的这个字段的一个信息啊。我可以在这呢描述一下,整体来看呢,这块都算是咱们叫字段表集合的这个信息,对吧,那这里边儿具体来说,首先第一个这呢,就是我们的这个字段名啊,或者这个字段名我们知道了这个类型,咱也知道权限呢,其实也知道,他这呢,其实相当于是完整的把这个信息呢,给我们这个反编译了一下,完整的声明了它的一个private in性的number。
05:22
那咱们在这个自建码文件里边看的话呢,先能拿到这个字段名索引是吧,所以呢,是不是就指向我们前面这个,那其实就找到这儿了呗。嗯,找到找到具体的应该是一个字串了。应该是找到这对吧,行,然后这块呢,是说明你这个字段的一个类型的啊内type就描述符嘛,行这个呢,是我们主要说的就是字段名,然后下边这个script这个其实就咱们这个字段描述符。描述符,这个对于字段来讲呢,它的描述符主要指明的就是我们字段的类型。这个字段类型呢,咱们前面也都说过了啊,I呢表示的就是int型,OK过了下边呢,就是咱们这个字段的一个访问标识,这个访问标识呢,是表示你是个私有的结构,那这个呢,就是默认权限,这这就没有了,对吧?行,那下边这个呢,是不是这三个都类似的,跟我们这三个是一样的对吧?行,我这块就不多说了,再往下都一样,对吧,类似的,然后像这个呢,它的flax就比较多,是public的,是static是final的。
06:27
OK的对吧,那对于我们说这个常量哈。这个咱们咱们前面呢,就讲这个属性的,讲这个字段的时候,在这个字段表里边儿,咱们提到过,说这个字段啊,它本身是不是也可以有属性啊,对吧,然后在最后我们这块还强调过这个一个字段呢,还可以拥有一些属性,比如说初始化值的这些信息,那对于一个常量属性来讲呢,它就会有一个叫constant value。这个这样的一个属性,那这个属性的话呢,这不我们就在这儿呢,也能看到的,看得到了,对吧,叫constant value,这呢是咱们当前这个常量的这个属性。
07:04
常量字段的一个属性,这个属性呢,就叫做constant constant value是吧?哎,这样的一个属性情况。行,那么这个属性里边呢,具体保存了,就是咱们这个常量的一个值,这个值呢是一是一个int型的一个一,就这意思,好,那再往下这块呢,这从咱们Java代码层面,咱们把它称为呢,叫构造器了,那在我们这个自解码文件这里边,咱们可以都把它看成呢,叫做方法。嗯,都可以理解成是这个方法,所以呢,整个从这再往下,比如咱这块呢,加一条这个线区分一下。这样分割一下对吧,然后CTRLC这个线上边这块的信息。这个行,我带上这个大括号吧,这块呢,主要是说咱们这个字段的这个情况啊,再往下边就说的这个方法的这个情况,所以下边这块呢,在这写吧。这个我写到这吧,也是啊。
08:01
这样可以对吧。行,那下面呢,就相当于是咱们这个叫哎,方法表的一个信息。发表发表集合的信息。OK,行,那这呢就对应的是我们一个一个的方法,大家就可以这样来看,那在这里边你看到叫扎p test,这是一个,然后下边的还有一个,这相当于是我们定义的两个是不是构造器啊,这两个构造器你看这块跟咱们使用这个接lab这块呢,就有这个区别了,咱们这块方法呢,是不是就在这块衡量的,这块衡量的我们会看到在咱们接lab里边,包括咱们自己去一个一个的来解读这个词解码文件的时候啊,都会呈现的叫做in。哎,都会呈现的这个呃叫in,那在咱们这个JP里边,它就是相当于给我们还原了,就还原成两个原始的这个构造器的这个信息。那这块呢,是有一个小的区别,这个大家关注一下行,这呢其实指明是我们这个构造器的一个信息是吧。
09:02
构造器一的这个信息,然后下边呢,是我们还有一个重载的一个构造器,通过这呢,我们也能看到这个构造器这块是可以重载的。行,那从这个自解码文件的角度来讲呢,就是你两个咱也叫方法吧,名字一样,除此之外呢,就是你的这些这个描述符只要有不一样的就行,描述符只要有不一样就行,那描述不一样的体现在就是比如说这个反应类型啊,呃,参数列表啊,不一样都算,但是咱们在这个Java语法层面,咱们强调过,主要参数列法得不一样,你要参数列表一样了,那即使反问类型一样也不行,对吧,Java语言不识别,但是对于我们最起码文件来讲呢,嗯,这里这里边只要不一样就行,这里边是包含了就是参数列表如果一样,这个反正类型不一样也行,这咱们前面讲的时候呢。一说别蒙了,咱们讲这个方法表集合的时候,你看我在这块是不是说这个事儿了。就这个问题啊,行就相当于我们这个字节码文件的话呢,它就是比较宽泛一些是吧,它比较宽泛一些啊行这就过了,已经说过了,然后再往下这块呢来看,不管是构造器也好,还是我们说这个方法也好,实际上它里边这个主体的细节啊,都是一样子的。
10:13
主体细节都一样子的,那咱们找一个,比如说典型的一个代表,说一个就行,说一个的话呢,咱们说一下这个叫收银份吧。说下这个收银份吧。以他为例来说,行。那展开来说,首先呢,这里边它其实是将我们把这个方法呢,它给我们做了一个反编译啊,你看把这个方法的完整信息都给我们呈现在这儿了,实际上这里边儿的这个public呢,是通过这个access flag呢才反馈出来的,包括你这个script就是方法的一个描述符嘛。大家写一下。方法描述符,这个方法的话,我们说描述符呢,主要包括的就是方法的这个行参列表。哎,然后呢,再加上一个返回值类型,这两块呢,共同构成了一个方法的叫描述符。
11:05
那你看这里边这是不是就是一部分,然后这呢是一部分,所以它其实是帮我反编译出来这两个信息了,然后这个flax呢,这块衡量的主要就是这个信息啊,这是它方法的一个方案标识。OK行,那再往下的话呢,这就提到我们方法里边的这个属性。那对于方法来讲呢,通常我们都会有这个扣的属性,方法的扣的属性对吧。那扣的属性里边都有哪些信息啊,咱们前面在讲这个资金码这个结构的时候,关于属性表。属性表这块打开咱们往上找,是不是专门也讲过这个关于扣属性的一个情况,你看在这都有对吧,那这块呢,你看匹配的一些情况。把它比如我们盯一下,跟咱这里边儿呢,其实就可以做一些相关的一些匹配了,比如说下边这个叫stack,这个stack这个叫locals,它俩是什么呢?知道吗。这个stack你看这写的是个三对吧,Stack对应的就是这个,就我们操作数占的深度的最大值。
12:07
磁带,它衡量的是操作数站。的这个最大深度。这个最大深度,因为是占结构,我们通常说的叫深度了,这个其实本质上来讲,他们都可以,包括我们这个局部变量表,都可以用这个数组结构来这个实现,对吧,但是呢,只不过我们这个sta呢,是数组结构实现的一个抽象数据类型,叫a dt,它是一个站的特点,先进后出对吧,先进后出啊,后进先出这样一个特点,那这个locals的话呢,是一个叫局部变量表。Los,这是局部变量表的一个最大长度,或者我们就就称为一个长度也行,无所谓最大了啊,这个就是长度,那么这个长度呢是二,这个长度是二,那从十物因分这个角度来看呢,一方面我们这个方法呢,是一个非静态的,所以它其中一个局无变量表里边的个数据呢,就是那个Z死对吧?那另外一个呢,就是我们在收银for里边,咱看下代码。
13:07
所以说里边我是不是定义了一个变量吧,这第二个呢,就是我们这个IOK,所以呢,这里边的一个就是2OK行二下一个参数呢,我们叫做X size,嗯,As呢就是参数对吧,Size呢就是大小,那它衡量了什么呢?就是我们这个方法叫哎,接收参数的个数。接收参数的一个个数啊,那这个情况的话呢,我们先保存一下啊,在咱们这个,嗯。这个叫什么?Jack z当中,我们比如说看一下这个叫收银缝是吧,这个收银缝这个code里边这个属性当中,关于我们的这个,呃,最大的局部变量表的一个长度,关于我们当前的这个,嗯,操作数占是吧,它的这个长度这个我们都有,但是呢,没有我们这里边提到这个叫as size是吧?那这个参数呢,大家稍微注意一下,那这个参数叫方法接入参数的一个大小,我们这里边儿呢,这个是一。
14:01
那这个是一,然后我们看看其他的方法。这个受针的呢,也没有型参,所以这也是一,那我们这个get number呢,它有一个型参,这个就是二,那因为相较于我们说的这个这次之外呢,那是不是它多了一个这个参数,所以呢,方法奇数参数呢,这个就是二了,包括比如我们再说一下这个构造器,这个构造器里边多一个参数嘛,所以呢,哎,除了我们当前这个这次之外呢,你看这还有一个二啊,还有一个所以所以这块呢,就是二对吧,就相当于任何没有参数的这种方法呢,这个2S都是一,只要有参数的话呢,它这个就变成二了。所以这个值的话呢,基于我们这个,呃,描述符这里边的这个情况,是不是也能够知道这个数值到底是几对吧。好,再回过来,嗯,再回过来的话呢,下边就是我们具体这个方法里边的,就是我们通常所生的声明的这个叫自解码指令了,对吧,那么这些自解码指令的话呢,像一开始的这个零。那这有02369对吧,那这个呢,咱们称为什么呢?称为呢叫做诶自建码指定的这个叫偏移量啊。
15:04
嗯,这个呢叫偏移量,这个咱们再往左边一点,然后这个偏移量就是记录它的一个具体的偏移的一个数值,比如我们后边还会涉及到像这个goto的指令,它可能直接就跳到某一行这个指令上了,那到时候你得告诉我到底偏移到哪,就这样一个情况,然后后边这个呢,叫BI push,这就是咱们下一章重点咱们要讲解的这些具体的自解码指令了,那b bif push呢,相当于是我们称为呢叫操作码up code,对吧?然后后边这有一个十,这个呢,具体我们称为它叫做操作数,诶叫做操作数,然后像这个该static呢,这里边有个景期,这个呢就相当于是指向我们字符串常量池当中的一个索引景七,你往上这边去找。找这个七七是不是就找到这儿了,那七呢,又相当于又索引到我们这个五十二点五十三了,你在下面去找五十二点五十三,就这样个情况,这个咱们前面也带大家说过这个事儿了,就是我们自己分析自己码指令的时候呢,来说过这个问题,行,那大家都相对比较熟悉,下一章呢,咱们重点呢,其实就说这些具体的操作码或者这些呢,我们称为呢叫自节码指令,或者叫嗯,这个注级符啊都可以行,然后再往后这块呢,这不就咱们这个前面呢,分析的时候呢,也提到过这个呢,就称为呢叫行号表对吧。
16:23
这个呢,我们称为,它叫行号表。行,那这个行号表呢,它主要的作用是什么呢?是不是就指明了咱们当前这个自解码指令的这些偏移量,与我们Java程序这个代码的这个行号的一一对应关系啊,哎,咱们在这写写一下啊,叫指明字节码指令的这个偏移量。与Java程序中,Java源程序中。这个代码的这个行号的一对关系。哎,一定关系好,那你比如说我们这里边儿呢,提到一个零。
17:06
零三三十对吧,零就是我们这个零,三就是这个三,30就是我们这个30,然后这个零呢,对应的我们整个代码当中是第36行,哎,36行这个代码咱们不能动。没应该没动过,你只要一改行号,这个跟他就匹配不上了,36就是它对吧,然后呢,接下来这个,呃,三十七三十八啊,三十七三十八。就是这样个情况,363738,就是这里边儿呢,就是我自己把指令那块那个零跟我这个账号代码中的这个36是匹配上的啊,就这个意思啊,然后再往下。这个呢,就是我们说的叫局部变量表。哎,局部变量表,那局部变量表你看一下,咱们刚才提到咱们这个叫收银会这个方法的局部变量的最大长度呢,是不是就二啊,所以在我们这个局部变量表里边呢,这个lo这块呢,它就最多出现零或一,但是注意啊,不是说我们只能出现两行了,有可能会出现三行,因为会涉及到这个slo的一个复用的一个情况。
18:06
那但是呢,就是我们上面如果写的这块是二的话呢,我们这里边这个索引呢,就只能是零一,那你有可能你复用个一,但绝对不可能说呢,出现012啊,那就成了三个了,这局部变量表,局部变量表里边呢,这个就指明了我们在相应的这个槽位零和一的时候呢,对应的这个局部变量是什么?零对于非静态变量我们都有个这次。然后呢,这里边儿还提到一个,你内部定义了一个变量,是不是叫I呀,所以它俩呢,都称为呢,叫局部变量。后边这呢,描述的就是你当前这个变量的一个类型,那说的很清楚,然后前面这个start跟length呢,这就指明你这个变量的一个作用的一个范围,从哪开始,然后偏移量是多少,你比如说从零开始,31就零加31,那就31其实就到我们这个程序是不是末尾了,所以这次呢,就是从头到尾都有效,然后这个,呃,这个I的话呢,它是从三的这个位置开始的,就从这个位置开始,然后加二八三十一,现在也是到末尾结束。
19:03
啊,这就我们称为局部变量表,然后呢,是这个保存或者叫刻画是吧,描述。这个内部局部。内部这个局部变量的这个相关信息,OK,这个呢,咱们前面也都提到过了啊,所以这块我们就这样过了,然后这块呢,你会发现这个带这个静态代码块,这个呢,确实从咱们代码层面来看呢,咱写的确实是一个静态代码块。没有问题对吧,但是呢,你会发现这个静态代码块呢,在咱们这个j class lab当中,它给咱们生成的或者对应过来叫CL,咱们在自建码文件中看到的是CL in呢,还是说像我们这里边反写出来是这样子的呢?诶注意咱们虽然没有看最起码文件里边有这个,呃,咱们在自己剖析的时候没有写这个静态结构,但是呢,你由这个非静态的这个对象的构造器方法,你应该知道,如果我们看资金码文件自己去读的话呢,实际上里边帮我们呈现的是这个CL in,只不过这里边呢,咱们使用扎P的时候,帮咱们又做了一个是是你可以理解成叫反编译了,编译成我们代码层面呢,写的是一个静态的代码块。
20:14
因为呢,我们通过是这样的一个标识,包括你这个参数的一个情况,你这也没有名字,咱们也能分析出来,它其实反编以后就是长这样子的,对吧,那具体的这里边这个细节跟我们说一个方法是一样子的,咱们刚才呢,以这个收音for这个方法做了一个典型的说明,然后最后这块呢,叫so fair这呢就是我们也称为呢,是不是叫附加的一个属性啊。附加属性对吧,这个附加属性呢,从我们最起码结构角度来讲,就是我们最后这个属性表集合。那这呢,就指明了我们当前这个字节码文件的一个原文件名,指明当前自接码文件啊对应的。源程序。文件名OK行,那这呢,就是咱们对这个JP解析以后得到的这样一个文件的一个整体的一个呃打型上的一个解析啊,那其中里边呢,我们略过的是哪一部分呢?就是咱们接下来下一章要给大家讲的这个呃字解码指令。
21:17
啊,是这样子的。
我来说两句