00:00
好,那么这个代码块完了以后呢,咱们及时呢做一个总结,这个总结呢,其实就涉及到了我们下边这个第五个问题了,就是关于这个属性赋值的一个过程,诶把这个说完之后呢,大家哎,包括我们刚才讲的这个事儿呢,会更清晰一些啊好,那这块我们来看一看,这块我总结的注意是实例变量啊。也就是说呢,我们针对这个非静态的属性,我们做一个总结。这个讲完之后呢,我们再最后呢,说一下这个静态的事儿就行了啊。好,那么大家呢,回忆一下,我们可以给类当中非静态的这个属性,也称为呢,叫实例变量复制的位置都有哪些呢?诶对,第一个我们提到了叫默认,之前我们还说呢,叫初始化是吧。好,然后还可以呢,叫显示。哎,初始化了是吧。对,前面还讲过叫构造器中。初始化这个呢,我们都认为呢,是你造对象的这个环节是吧。好,然后呢,比如我这块画根线的话呢,下边呢,是不是对象就有了。哎,原来呢,我们提到了下边呢,叫。
01:00
啊叫有了对象以后是吧,哎,通过。那叫对象点属性。对,或者呢,你是。在对象点那这个方法。哎的这个方式啊,进行这个哎赋值,这时候我们就叫做赋值了,这叫初始化了。就是造对象之前的,这叫初始化。OK,那现在的话呢,我们又讲了一个是不是代码块的问题。两板块是往这个线上面放还是下边放。对,应该是往上面放,因为我们刚才呢,呃,在这个讲这个内容的时候呢,你也会发现,当我们去扭对象的时候呢,不就执行了吗。啊,所以说它是在创建对象的过程当中执行的哈。所以呢,我就放上边了啊,放上面呢,我们是关键是写哪是吧。斜哪,我们先放这儿吧。嗯,这个呢,我写成叫呃。代码块中。哎,进行一个,现在既然是在上面呢,都叫初始化吧。
02:01
啊,就这样写了哈,好,那么现在的问题是什么呢?我们想看一下整个这个过程,它执行的一个先后顺序。以前呢,没有讲这个代码块,我们其实已经有过一个顺序了,是吧。就是一完了以后二。二完了以后三三完了以后呢,四。哎,这不是咱们原来的时候讲过这个事儿吗。在哪讲的?加构造器的时候。诶看一下啊,构造器这不是在这儿吗?构造器讲完以后呢,这会我们在这个位置呢,这不说了,一个复制的先后顺序,这不是在这起的吗。证据都找到了是吧。这个现在呢,是我给大家讲第一个阶段哈,后边呢,还有第二阶段,第三个阶段,老师一般的后边几位老师经常会问一个说你们前面讲过这个没有。大家一般都说没有是吧。然后那个老师就找到前个老师说你们没讲那个什么吗?老师一般都说讲过呀,是吧,嗯,一般都是这样的啊。
03:00
所以呢,大家得争取呢,把讲完的内容呢,你得留下来啊,要不左耳朵进右耳就出麻烦了是吧。讲了一个。这个这个咱说这个学习的话呢,不是有一个叫什么费曼学习法是吧。嗯,对,可能有听过的啊,就是最高效的这种学习方式呢,就是你把它讲出来是吧。从这个角度来讲的话呢,其实咱们讲听一天课哈,收获最大的其实是我自己是吧。嗯,大家这块可能就是过了一下是吧。所以呢,相互之间有问题的时候呢,互相讲一讲,说一说是吧,你就能记得住啊。尤其呢,你要大家都住一起,晚上的时候呢,你们排排班。比如说三个人四个人住一起,你们排个班怎么着呢,每天晚上回去以后啊,今天是你是吧,你把今天讲的内容呢,你自己说一说啊,比如说不低于十分钟。啊,你可以做一些小抄是吧,都可以啊,不低于十分钟说说完之后呢,其他同学再补充。呃,每天一个人,嗯,这个排个班,嗯这样坚持下来的话呢,一定会看到有区别的啊。
04:04
OK。好,这个我们再拉回来,这儿呢,是我们之前讲过的一个顺序啊,1234,那现在呢,我们想把这个五呢塞进去,问题是塞到哪。嗯,那这个我们就得是先猜一下,然后我们去证明是吧。啊,要不你证明的时候你都没有方向了啊。嗯,大家觉得呢。二三之间。还是三岁之间?呃,感觉应该是在二的后面或者三的后面这样是吧。行,那咱就三对三的前后呗,啊行,那咱们就来证明一下看看啊。好,这块我们把这个呢就收起来了,现在我们来看一下这个事儿啊,这个事儿的话呢,我们也写一个具体的代码。Field的一个测试。这么着啊。好这块呢,我们比如来一个class,那咱就叫吧。
05:02
Order啊,你可以理解成就比较抽象的一个类了啊。好,这个的话呢,我们声明啊,In型的叫ID。哎,我就先拿它来进行说事了啊,因为呢,我们已经有了前面的一些这个经验了啊,所以关于这种显示赋值啊,哎,构造器赋值啊,这个顺序呢,我们是比较清晰的了。哎,咱们先这么着一下,我这儿呢,复制为一个一。然后这块呢,我们先造一个对象。OK啊,那么O1呢,我们去调奥德ID,毫无疑问呢,它一定是一。来跑一下。行,这个没问题了啊,这个没问题,以后呢,下边的话呢,我们整一个代码块吧。哎,代码块里边呢,我们把这个order ID呢改成二。先看一下你可不可能是在这个显示负值的前面是吧。啊啊,我们这时候呢,先跑一下。这个结果呢,你发现是二,那它一定是先有了一二呢,又把它覆盖掉的。
06:03
所以呢,它首先呢,是在我们这个二的后面了。啊,这没问题啊,然后下边的话呢,我们再要想验证怎么办呢。得整构造器了是吧?啊构造器的话呢,诶,我们看看怎么办啊,我其实呢,就也可以整一个空参构造器,我在这里边儿就给你写死得了。写这个三。那我们呢,在调这个构造器的时候呢,一定会执行它了。现在关键问题就是它是二还是三是吧。好,来走一下啊。你发现是三啊。呃,那说明呢,这个三应该是把二给覆盖了,那进而的话呢,它应该在三落到气的前面是吧。哎,在他三的前面,刚才也看到了,应该在二的后面了,那是是不是我们放的话呢,就应该放到这儿了。就诶就是这样一个过程吧。行,诶这儿呢,我们就把这个顺序的给捋了一下啊,然后这个事儿的话呢,我们还可以怎么办呢?诶你看刚才我这个代码呢,是执行过的哈,或者说你这个代码又改过啊,你得重新的再去做一个编译,诶确保呢,我们现在生成的这个自解码文件跟你这个代码是一致的啊,我现在要干啥呢?诶我是不是又要看这个自解码文件了。
07:14
哎,咱们前面提到过哈,再再唠叨一遍,大家可以呢,在这个settings这个位置啊,这个插件啊,你呢,把这个叫j class lab啊,然后battle code,在这个marketplace这块你可以下载一下啊,下载完以后呢,诶把这个代码你跑一次,或者说呢,你在这块不用跑,你就直接的编译一下,针对一次解码文件哈,我这块呢,光标记着一定要是点到下边这个里边。我看的是具体的类啊,它的这个资金码文件了啊,光标在这里边儿的任何位置都可以啊,我们去点view下边有一个它点开。此时的话呢,我们查看的呢,就是当前这个order了。这个order呢,大家你看这个方法啊,这块的话呢,我们就有一个in的方法,前面我们也提到过啊,这个构造器呢,会以in的方法的方式呈现在这个自解码文件当中。
08:01
在这个里边呢,我们看一下所谓的这个代码。啊,那就是我们诶看到的右边的这样的一个代码了,这个代码呢,其实啊,我说他就暴露了我们加载的一个顺序,虽然说这个大家看起来呢,会比较吃力一些啊,但是呢,有我在是吧。过一下啊好,这呢,我们说呢,这个构造器呢,会以这样的一个方式去呈现,但是其实你发现呢,呃,不完全是构造器。它会把呢,有一些代码呢,也放到这个方法里了,构造器呢,只是说其中最主要的部分啊,都有哪些呢?诶首先我们一上来发现这里边呢,就要加载一下,呃,漏的这是零,就是角标零的位置哈,其实就是我们当前这个,嗯,这看能是个方法的话呢,方法里边我们说它就应是个战针,战争里边会放这个所谓的局部变量。啊,这就是你局部变量第零的位置啊,这零个位置是谁啊,诶,你可以搂一眼啊,这个你把它再点开,这有一个叫局部变量表,这个零的位置其实就是Z啊。说白了,就是你当前正在创建的这个对象了。
09:01
当然这个呢,这是小事啊,就是现在呢,我们主要通过他呢,我要调这个方法啊,上来呢,大家就会发现呢,它会调这个object的这个方法了。这呢,就是我们所讲的,你上来是不是就胸破空了?诶,它其实对应的是这个操作,你没写,这不相当于也有吗。哎,这个我们顺便就验证了一个知识点啊,这个不是我们要说的重点,重点的话呢,是下边哈,诶这个位置就是我们呢,诶取了一个长量,这个一不是角标的意思啊,就是常量一的意思,这个一就是这个一。诶,所以呢,我们首先呢,针对你这个order ID哈,是不是给大家复制为一了。啊,我这先把一拿过来,然后给你赋了个值。啊好,接下来的话呢,我们又取了一个二二呢,就是你这个二。然后呢,给你是不是又赋了个值。那接下来呢,我又取了个三,就这个三啊,这不又给你赋了个值吗?所以这个顺序呢,不就能看到显示赋值代码块赋值构造器赋值是吧。诶跟我们刚才测试的这个呢是一样的,也就是说这个二跟三呢,它是负过的啊不是说呢,我们这块呢,这个一看结果是三,说这个负过没有负过,在这儿呢,看得很清楚。
10:08
啊,没有问题啊,好,那么真实的这个结论就是这样吗?其实还不太对。怎么叫不太对呢,诶大家你会发现哈,这里边儿呢,我们把这个显示的赋值写上面了,构造代码号赋值写这儿了,我要是这样放的话。人家说这也可以啊。这怎么可以呢?说你这怎么这先用了后声明的呢。是吧?这个咱们等会儿说啊,咱们先不着急一个一个来,诶我现在呢,首先你注意我把这个代码块复制,我写到这个显示复制的上面啊,那么这个时候会是什么样呢?我先把这个注释一下,不要让它影响啊。哎,只有显示复制和代码块中复制好,这时候看结果。一朗。那只能说明呢,是不是先有的二,后有的一。
11:00
好这块呢,你看我刚才运行过啊,我刷新一下。刷新以后赶紧看啊。后导器呢,这块首先也会先去调Q波空,这没问题啊,然后呢,我们看先有二根据奥的D复制了是不是后有意义。有负的值,所以显然呢,是不是这个代码块的负值就稀了。所以这块呢,我们要这样写呢,不太对。啊,应该呢,是把它俩是不是放在一起。哎,我这样一下。啊,也就是说它俩呢,到底谁先谁后呢,就看谁先声明谁后声明了,所以这块呢,就要显示初始化啊这个呢,我们把这个五呢,是不是应该得放到这儿了是吧。跟着V一下,这个呢,我们来个叫货吧。所以按照先后顺序的话呢,应该是先这个在整个这个在这个,然后最后呢是这个。哎,这呢才是我们想要的一个顺序,它这才是对的。啊,先明确这个问题啊,只不过呢,在咱们平时开发当中啊,咱们通常都会把这个呢放到下边。这只是说我们的习惯而已,因为你放下边,你可能会说,呃,先有的这个显示,后有的它,但是主要原因还是因为你之前都放下边而已啊好,那么说一下下边这个问题,说为什么我们把这个写上边呢,这块也不报错呢。
12:14
是吧,诶这个事儿的话呢,首先还是有一个误区哈,这个误区呢,诶我呢,再换一个场景来去给你解释。比如说这呢叫E的方法。啊,这个呢,我们是public,这个叫sleep的方法。啊,具体方法体我就不写了啊,然后你在it里边呢,是可以调sleep的。啊,真没问题啊,这个呢,如果按照你上面这思路的话呢,这块也有同样的问题啊,你是不是先有eat后有sleep,怎么上来就先sleep了。这不还没声明吗?你发现这里没错呀。啊,这个咱们怎么去解释呢。对,我们只需要考虑呢,就是首先编译的时候,他会看里边调这个方法了,这个方法有没有有。是吧,那这个有的这个方法,这个你能确保我们在调用它的时候,内存中就有了吗。
13:02
哎,所以呢,我们在哎加载这个类的时候呢,咱不是把这个类呢,就放在了这个方法区了吗。其实这时候呢,你这个也好,Sleep也好,首先这个方法呢,其实就就都加载了是吧。所以只需要确保我们在调这个方法之前,你这个方法呢,加载就行。诶,我在调它的时候呢,是不是调它,然后一的方法,你加载了我就调你,然后你这里边儿又呃调了这个sleep sleep也加载了,那我这块就能执行。所以呢,就不会报错啊。但我们这个事儿也类似的方式呢,可以去解释。啊,这个我就不想说的那么细啊,咱们以后在反射的时候呢,会提到这个类的加载的详细过程啊,那么我就抽取出来最核心的点,核心点是什么呢?就是这个order ID呢,咱们在整个类的加载呢,其实它有一个细的过程哈,在其中的某一个环节的时候呢,它就先把这个order ID呢已经给你加载了,而且呢,还给你做了一个默认赋值就是零。啊,说明这个时候呢,这个属性呢,就已经有了啊,在后边的这个环节当中啊,才开始给你做显示的赋值和代码块的赋值。
14:06
那这块呢,发现你是先有代码块复制,那我就接着把你这个O呢改成二了,然后后边就把你改成一了。哎,在你做这个操作之前呢,它的前一个环节这个属性已经加载过了。所以说不会出现的,说我写在上面,诶怎么不报错呢,因为他已经都有了。啊,注意一下就行啊。好,这呢就是我们说的这个场景,那如果你要是听得不太明白的,你就记住它,这个可以写上边,但是一般的我们都写下边。就完事了啊。好,这个结论的话呢,很重要。啊,就是给属性赋值的时候呢,它的几个位置以及先后顺序。OK啊好,那这个事呢,我们就告一段落了,这个完了以后的话呢,我们稍微的给大家去说一下这个叫in的这个事儿啊。这个音译的话呢,诶我们说呢,这是一个超纲的内容了,正常来讲,咱们学基础阶段呢,用不着讲它,但是呢,讲一下它呢,我觉得更有利于大家呢,去理解这个核心的一些点哈,我们可以通过这样的一个插件呢去查看,诶好,那首先呢,关于这个利的方法呢,我们做个说明。
15:09
这个呃,以你的方法呢,在一个自解码文件当中可能会有多个哈。这个音乐方法有几个,取决于我们当前这个类当中声明过几个构造器。啊,在这写一下啊。说一的这个方法。啊,它呢是呃,显示在。啊,或者这个这样说吧,啊,在子解码文件中。啊,可以看到是吧。啊,然后呢,每个in这个方法。哎,对应着。哎,都对应着一个类的构造器。哎,所以呢,这个言外之意呢,就是我们声明了几个构造器,就会有几个引内的方法。啊类中声明了几个。扩大器。就会。
16:01
啊,有几个一年的方法。诶,这是这样一个情况哈,啊第二点啊,那既然说呢,我们这个构造器呢,跟它是一一对应的啊,而且呢,我们在这个自检版文件当中啊,你也看不到说呢,字段只有属性的意思啊,属性方法它也没有专门一项叫构导期。那说明我们构造器呢,就是以音译的方法,这个形式呈现在我们自加码文件中的。啊,这说一下啊,这个构造器啊。这个这个这样说吧,哎,编写的代码中的这个构造器,呃,它呢,我们说过是跟方法呢,是完全两个概念啊,方法是方法,构造器是构造器。当然呢,我们编写代码中的构造器呢,在编译以后。啊,就会以。哎,这个这个方法的这种方式呢,去呈现啊。哎,这个呢,其实跟我们上一个点呢,这不也是呃,一脉相承的。相当于是换一个说法啊,但是呢,我们下边一个点啊,这个伊利的方法呢,跟它虽然是一一对应的关系,但是呢,这个in的方法呢,它不完全内部的代码呢,是构造器中的代码。
17:08
那这呢,就对应的类的方法中的代码都有什么是吧。说伊利的这个方法。啊,内部的这个代码。啊,包含了。啊,包含了什么呢?诶,包含了这种实例变量的显示赋值。代码块中的这个赋值和。诶,构造器中的代码。哎,是这样的一个结构的综合体。那我们回过来简单的给大家呢,再说两句哈,比如说诶这儿呢,我有一个构造器了,这个super你写不写呢都不重要,不写也有是吧?啊比如说这样一行代码哈,这个构造器呢,我们就会在这呢对应着一个叫in,然后这个in呢,诶说这里边都会有什么代码呢,你发现了,你这里边呢,似乎什么也没写,其实呢,我们至少呢是有一个super空。
18:00
哎,那你这个修空的代码呢,就会呈现在这儿,这呢也是我们所谓的就上来就会加载负类了,所以一上来先去,诶做负类的这个事儿啊,然后剩下这个代码的话呢,你发现呢,我们这里边没有了,没有的话呢,你注意它不光是对应你构造器了,它会把这个显示的赋值和代码块中这个执行的这个操作呢,都放到这里边。那这就我们下边的这个事儿,那如果我要是再声明一个构造器。啊,比如这块呢,我就印一个叫order ID。在这里边呢,我们就C4.2order ID等于order ID,我这样写的哈,好把这个呢,我就不运行了啊,咱们直接光编译一下。编译完以后的话呢,我这块再刷新一下。好,这块大家你再看,发现在此时这不就有多个in了吗?哎,这有俩是因为我们这儿呢,就有俩过道器啊,然后呢,这个上面这个呢,自然而然就是你上边这个,下边这个呢,就是你下边这个,好,我点开下边这个的抠的,你发现这个代码呢就比较多一些啊,诶它呢首先也会涉及到这个super的事儿。哎,所以上面这块呢,还是这个super的事儿啊好,接下来你看这有个一也好二也好,是不是就都还是你上面这个显示复制和代码块的复制,就是该有的还都有。
19:08
啊,就是我们下边这块一直到这儿啊,然后再接下来的话呢,我们这有一个关于ID的一个赋值,是不是就把你这个角标一的这个值,角标一是谁呢?你要有兴趣看的话呢,这不就在这个位置啊,角标一不就是我们这个行参的啊,叫order ID吗?然后把它呢,呃,又重新的给我们这个order ID这个属性呢,又做了一个赋值。哎,就相当于是这个操作了。啊,这样啊,诶所以呢,我们看到的就是,诶这个你要通过这个构造器去造对象的时候,咱们不是也说过哈,它也会先有显示复制和代码块的执行,然后再去执行你这个操作了。啊,对应过来呢,在自己码文件里边看到的,其实就是个in方法。啊就行了啊好,那么从这个角度来看的话呢,哎,你说这个意念的方法,它的作用是什么呢。呃,这个方法呢,我们说呢,它对应的是个构造器,但是它不等同于构造器的代码是吧?诶这个方法的话呢,正如它的名字。
20:06
哎,所显示的一样,它呢,就是用来。哎,初始化。当前创建的对象的信息的啊。当前。哎,创建的对象的这个。啊,信息的。啊,就是用来做这个事儿的。咱们构造器的话呢,呃,不是也可以用来做初始化信息吗?它呢其实呢,在编译完以后呢,就是融合在了这个in当中。哎,这个大家了解一下,注意就行啊,哎,大家呢,还是重点要强调的一个概念是什么呢?就是构造器是构造器,方法是方法。哎,字节码文件当中呢,确实是没有构造器这个东西了,是以方法的方式呈现的,但是呢,大家呢,在编写的时候呢,还是要把构造器和方法呢区分开,是不一样的东西啊。诶就可以了,好这个呢就说到这儿,接下来说呢,诶有一个开发中的一个经验之谈哈,说呢,我们给这个实例变量赋值的位置啊,其实挺多的哈,说可以显示赋值,也可以代码块中负,还可以构造其中负,那我开发中我到底怎么选?
21:09
我现在有一个成变量是吧,我要赋值的,我在哪写。你说你你怎么选。哎,咱们这块呢,主要说的是这种实例变量啊。哎,就是每个对象呢,可能这个值都不一样是吧。怎么选?啊。啥适合选啥,那你这个啥适合是怎么确定的呢?是题面跟你说的。啊,那那这时候就看一个什么呢?就是这个需求文档是吧。就是我们写代码的时候呢,现在的这个模块呢,我们会有这个需求的,呃,需求分析啊,对应的它有这个需求的一个文档了哈,呃,这个文档里边如果你写的非常的详细,就像我们,呃,怎么着呢,这个写那个UR的那个类图一样是吧?呃,下面还配一些相关的说明,呃,如果呢,写的这么详细的话呢,那你这块人家让干啥你就干啥。
22:02
这个呢,只能说很low,这就是码农是吧?你就跟农民啊,人家让你干啥,你这块你就耕地啊,这个把种子一撒。这个撒点化肥一浇水完事了是吧,没什么技术含量。啊,那么呃,再者呢,你也不要依赖于说这个文档给你写的这么详细,可能一些大公司的话呢,给你写的很详细,包括呢,像当年这个,比如说咱们对日开发,日本人做事还是挺严谨的啊,这个外包给比如说东软啊,做这个外包的项目,他们写的文档呢,就非常的详细。那这块呢,对于咱们这个成员来讲呢,就不需要你有任何的发挥了,你就按照他的要求,他让你定义什么样的变量,什么类型的,你就这样去写就行,不需要你思考是吧。那么比他高级一些的话呢,就咱们说的就跟叫工程师的是吧,就跟盖房子一样啊。这个时候呢,对你得有这个设计的概念,这个房子呢,得防震多少级的啊,怎么这个去架构是吧,更合理更安全啊,我们软件开发这个层面呢,就是你这个代码的这个,比如说你得承载着这个高并发的这种场景,你的扩展性得好是吧,耦合度得低,我们有很多的标准呢去限制它。
23:11
这个时候呢,你整个这个从最初的这个软件的架构,你使用什么样的框架选型啊,这个呢都需要考虑,这个呢就可就会更高级一些,换句话说呢,就是你那个需求文档不也是人写的吗?谁写的呢,写的那个人是不是就更高级一些。啊,所以大家呢,咱们平时一说这个感觉开玩笑说码农是吧,工程师其实的话呢,你可以理解成他是不同的地位的啊,你是只只是呢,看着人按照人要求去写,还是说呢,你是有思考在里边的。啊,它是不一样的哈,那这块我们想谈的就是说我们要是设计的话呢,你怎么去来选,这是一个小问题是吧。啊,那我们会发现呢,呃,你要是显示赋值的话呢,如果我们是实例变量,你用的是显示负值,那不就意味着每一个创建的对象的这个值是都一样的是吧。啊,比如说这块我们这个值,我写的是个一,你在构造器里边,你没负代码块也没负哈,那你每创建对象呢,大家都是一。
24:04
啊,这就是他的一个特点哈,那如果你想体现每个对象的这个属性值不一样的。哎,代码块中可以吗。这个一会儿说啊,首先呢,我们想的是构造器啊。对,你比如这auto ID大家都不一样,那我就在造对象的时候呢,我就选择这个,哎。有这个参数的啊,每次呢,造这个对象的时候,把这个值呢,给你指定一下。所以呢,关于这个显示复制和构造器的复制呢,比较容易区分啊。这个呢,哎,我们说呢,显示呃赋值不叫赋值了啊,它呢比较适合于。嗯,比较适合于就是每个。对象的这个属性值相同的场景是吧。属性值。相同这个场景好,那么对于我们这个叫诶构造器中赋值。诶他呢,诶就比较适合于就是每个对象的这个属性值不同的这个场景,你可以呢,在呃造这个对象的时候呢,诶你通过行参的方式呢,给他去做这个复制。
25:07
好,那么这个代码块中赋值呢。其实偏向于他。是吧,哎,其实偏向于它啊,但是呢也稍有不同,因为这个位置呢,我们可以很灵活,比如说我是从网络当中加载的数据啊,我从本地的这个某个文件中加载的数据啊,甚至说呢,我这块呢,去取一个随机数啊,啊这呢就体现了有不同的,但是你刚才这个操作呢,似乎写到这里边儿也可以是吧。哎,所以从这个角度来讲呢,这个代码块呢,我们用的确实少一些啊,所以呢,咱们在平时开发当中啊,呃,像这种非静态代码块呢,一般我们都想不起来用。因为呢,你要是一个固定都一样的值,我就显示负了。你要是一个这个不一样的值呢,我就写到构造器里了。然后呢,你说这里边儿可能还有其他逻辑,那我就写到构造器里边,彼此之间我用这次呢去互相调一下,也能够减少冗余是吧。所以呢,有时候我们就想不起来用它了。啊,注意啊,但是。
26:01
下一个问题啊,静态代码块跟这个非静态不一样了。因为静态代码块呢,我们不会选择在构造其中复制的。所以相较于我们刚才说的这个实例变量来讲,它少了一项是吧。啊,你你静态代码块,诶这个静态的这个属性的话呢,我们就不再构造技服了,因为你是跟对象相关的,我静态是跟类相关的,我就不会选你了。那么静态的这种变量呢,咱们其实呢,就是要么默认复制,要么显示复制,要么代码框中复制,这个就不考虑了是吧。哎,那么进而的话呢,我们,呃,就像刚才我那会儿举的这个例子一样,这不又回归到这儿了。诶,你要是显示在这负个值呢,那行那就写这,但是呢,有的时候呢,这个逻辑呢,比较复杂,一行代码搞不定,那我们就得考虑用静态代码块。哎,就这么个意思。就可以了,行,跟刚才我们这个内容呢,就又连在一起了啊好,那么整个这个事儿呢,我们就说完了,哎,我就不写代码块了,因为用的呢,其实啊,对于实例变量来讲,用的确实不多啊,大家呢,需要做的事呢,就是你基本会用,然后呢,以后我们开发的时候呢,看源码的时候呢,你看到代码块了,你得知道呢,它什么时候执行的。
27:10
啊,静态的什么时候执行,非静态什么时候执行,基本上你就够了。好,那么这个属性复制的过程呢,咱们就说完了,接下来的话呢,我们来看看这里边这个练习,还有这个写真题啊,先看这个练习,练习里边呢,是这样的一道题目。啊来我们一块儿来看一下啊,整体来看的话呢,这里边儿有这样的几个类,首先呢,是这个叫root类。啊,这有根儿啊,静态大板块,非静态大板块构造器。好,然后呢,这里边儿一个叫密啊,密里边呢,同样的静态代码块,非静态代码块构造器,构造器呢,写两。哎,大概有个印象,然后再下边这叫leaf就叶子啊,哎,继承于我们这个me,然后现在非静态构造器好完事了啊,接下来我们看一看这个代码的一个执行,首先呢,我们先看第一行啊,我们new一个这个leaf的对象啊。那么你这个对象的时候呢,毫无疑问呢,它会涉及到当前这个类啊,它的负类啊,负类的负类啊加载,包括呢,相应的一些结构的执行了,所以这块我们要分析的就是先后执行的一个顺序。
28:12
呃,能够看到的就是在相应的这三个类当中,依次的集成关系都有静态的代码块。还有非静态的,包括过道期了啊,那大家这块呢,会觉得我们最先执行的应该是哪些呢。诶对,首先呢,静态跟非静态的来分,应该是得先静态是吧,但是你先静态的话呢,这也有,我们leaf里边有静态的代码块,密也有,Root也有,那他们仨之间谁先执行。这块一定要注意啊,我们在进行类的加载的时候呢,我们一定是要先加载负类的。呃,然后呢,再加点此类的。换句话说,咱们讲过方法的重写是吧,重写重写你是不是得先有复类的方法,然后呢才能覆盖人家。
29:00
那既然这样,你是不是得先加载负类了?你要先加载子类,然后再加点父类,那父类把子类给覆盖了,那到底是谁重写谁了?是吧,诶所以一定得先加载负类的啊,那么这个加载呢,其实就理解成是这样了,当我们通过这个leaf呢,造对象的时候呢,首先它会super,就你没写这也有super了啊在super呢,就找到负类了,找到负类的时候呢,负类这块呢,它要加载。比如说你调它指定那个构造器,呃,比如说这块我们调的是这个带参的这个构造器了啊,你调那个构造器的时候,它调这次了,这次呢默认又super了,所以就翻到我们这儿了,这儿的话呢,找到它构造期,它构造期这块呢,它没写其实也是super,所以呢,我们其实最先加载的是。对,Object。诶先加载它啊,只不过呢,这个类呢,我们里边咱们也改不了人家代码。啊,人家都已经定义好了哈,诶,所以呢,这里边儿这个也没有输出语句,所以我们看似呢,好像没加载,其实是先加载它,其次呢在加载它。那既然加载它了,是不是就涉及到这个它的执行了。诶对,所以说他先执行,他执行完以后注意啊,先不要着急去执行这块了,我们先得把类的加载呢,先都执行了。
30:05
所以说我们看到这个执行的结果呢。哎,先得有这三个东西。Root这个代码块的一个静态代码块的执行,意味着root类的加载,然后呢是这个mid类的加载。然后是我们这个啊,Leaf这个类的加载,所以这三个为代表的呢,是类的加载完成了。哎,然后下边这块呢,才涉及到你现在呢,是要造对象了,然后我们再回归到你这块呢,通过构造器,呃,造对象的这个事儿。哎,下边这块呢,再按照我们说的这个逻辑来了啊,我把这块呢,我稍微的盯一下啊,就是这个静态的加载之后的这个事儿啊。好,这个呢,其实大家就比较好理解了,我们先去扭一下这个lef,这不是先找他,他呢再找弗雷,弗雷,诶其实这块呢,就翻到我们这块先执行它的这两个逻辑了。这个注意一下啊。就是静态的加载完以后的话呢,再执行的时候呢,你通过休克休克休克,所以呢,一直翻到我们,诶最顶级的这个副类这块呢,先考虑它的构造器的一个加载啊,因为这块加载呢,就涉及到这种非静态结构的一个加载了。
31:15
比如说你非静态的方法等等是吧,然后你此类在加载,然后你才能够重写我啊好,那这块加载的时候呢,咱们说过这个代码块的执行要早于构造期吧。所以说我们这块呢,就先输出了这个。呃。诶,我把这诶这个我重新再解一下啊。哎,这块干脆我就都这样解一下吧。好过来啊,诶你把上面这三个呢,先给它干掉是吧?诶所以这块我们看到就是root的普通的哎代码块它的一个执行这个执行完以后的话呢,诶这不又执行的是这个吗。诶就是它,所以这块关于诶root这块呢,这不就加载完了。下载完以后,你看你当初是怎么上来的哈,我是通过super呢,先调的是他。
32:01
他呢调的是这个,这个呢是翻上去调的这个刚才的root里边的这两个逻辑。那回来之后呢,应该是先到这儿了是吧。到这的时候呢,你注意呢,代码块,哎,过道器的执行要晚于这个代码块嘛。所以呢,现在有这个它的代码块的执行。他执行完以后的话呢,我们是刚才那个子类呢,是调到他,他又调到这个,所以现在应该是轮到他了。所以先执行那个无餐的,这个执行完以后呢,相当于这次就执行完了,所以这个代餐的呢,这块就执行了。啊,这个执行完以后的话呢,相当于我们下边你调到这个super里边的这个执行完了,诶该按说该执行它了,但是执行它之前呢,注意先得执行。代码块是吧,哎,所以这个代码块呢,他先执行,然后再执行这个。啊,这样的一个过程。来注意一下哈,好,那么这个过程的话呢,我们在这儿呢,对应的有一个口诀哈,这个加载的整个过程呢,我们叫呃,由父及子。嗯,是啊,由父及子啊,静态先行。
33:04
哎,这个应该能理解啊,先加载父类,再加载子类,然后静态的结构呢,要早于非静态的执行。然后在非静态里边呢,这个咱们刚才那会讲复制过程也说了啊,静非静态代码块的执行要早于构造器的执行。啊,而且呢,他们合在一起,实际上呢,是构成了伊尼的这个方法是吧。哎,我们也提了一下啊,而且这个内的方法大家注意啊。呃,这个在资金码文件里边是一个方法,这个方法呀,不是让我们通过对象去点掉的。它是自动执行的是吧。啊,这个不是让我们调的,不像你那个eat呀,Sleep呀,是你通过对象啊去调的啊。啊OK,这个呢,就是我们说的这样的一个题目啊,大家关注一下啊,知道这个类的加载的过程啊好,接下来的话呢,我们看一下这个真题啊,先看第一道问题。啊,这块呢,就会只要我们讲完这个代码块以后啊,关于这个对象创建过程当中,这个加载这个事儿呢,其实就都讲完了,讲完以后的话呢,其实就会有一系列的问题,就来恶心你的啊。
34:05
实际上我们在开发当中啊,咱们不会写的特别复杂啊,就是这个笔试题呢,去恶心你。哎,这块我们就拗了一个,Hello啊hello,币在这呢。啊,为了方便呢,我们这么着啊,把他呢盯一下啊。上面呢是这个哈。好,我就拗了一个,哈哈。因为一个hello呢,那不就是掉它吗。叫他呢,按说就该执行他了是吧。但因他之前呢,你记得有个super克。Super泊尔空是吧,Super空的话呢,就翻到负类这块了,负类这块呢,你看人家有静态的,所以这块呢,是不是先他执行。然后再。这个执行。是先把类的加载先搞定是吧,然后呢,再考虑你当前要创建对象呢,是要它的这个构造器了啊构造器的话呢,修呢,先跑到这儿来这儿,诶先跑到这儿来这儿呢,注意先得执行它。所以这是三是吧。三完了以后呢,四,然后这个super空呢,现在就完事了,然后这个是不是,诶这个要该五了,但是注意这是五是吧。
35:05
然后这个是六吧。呃,其实刚才我们那个做完之后呢,这个呢,比它要简单一些。OK啊,好。走一下这个顺序啊。哎,是不是静态先行啊,由负即子静态先行,然后呢,先把这个负类,这是代码块里的,这个是你这个构造器,代码块构造器没问题啊。好,这个就过了啊,然后接着我们看这个第二道题啊。这个呢,看着呢就感觉有点酸爽了啊。有点酸爽了,哎,时间关系啊,这块呢,哎,咱们就直接来了。诶这块呢,你想拿到这个代码之后,你先看啥呢。先找妹哈。上来就直接找入口啊。如果一上来的话呢,这块呢,我们就去X等于谁。啊,注意啊,我一上来就等于谁这块呢,其实你在执行这个魅方法,这个方法是静态的,虽然说叫入口了,但是它仍然是当前这个类。
36:03
掉的是吧。那就意味着我们这个类呢,是不是也得先加载。非要加载的话呢,其实你相应的这个呃,静态代码块啊,是不是都会执行啊。所以呢,我在直行这X等于谁的时候,其实这些东西啊都。都执行过。是吧,诶注意都执行过了,已经啊这个方法呢,叫静态方法,他不会执行。对吧,诶他呢,你调的时候才执行啊,像这呢,都已经在我们这块写它的时候,这都执行了啊,所以呢,他判断X是几,那咱就是不是得走一下啊。诶像这儿呢,看X这儿,首先它的默认值是零了。默认复制以后呢,接下来你就看这个静态里边的复制了。注意这块就故意的混淆你的啊,我这定义那个X是5X减减这个X改的是它还是改的是上面这个。是下面这个还是上面这个。注意是下边这个啊。这不就是就近了吗?
37:00
哎,所以这块你按住CTRL键,然后一点这不就在这儿了。当然你笔试的话呢,它是纸上写的,你也点不了是吧。所以你得知道这就近了啊,所以这个呢,就故意混淆你的啊,X还是零。这个呢,就过了多个静态代码块,咱们说按照顺序执行啊,所以该他了。这个S减减毫无疑问呢,它就变成负一了是吧。好负一啦,然后那这几个是不是就是负一了。咱们一边说一边就执行了啊好,是不是负一,那就没问题嘛。OK啊,所以这个负一呢出来了。嗯,接下来的话呢,是不是就。就走这个呗。上面你看了一下这两个静态代码块里边也没有去操作Y跟C哈,那人家就都还是默认值。啊,那这个最减减。负一了是吧,好,接着调ma就该这了吧。这个注意这是负一了啊,那整个这个呢,叫后加加。先取出来负一是吧,这就Z变成零了啊。好,然后再加上一个。
38:00
呃,这个呢是先加加的,所以这块呢应该是拿一来考虑,Z呢也变成了一了。好,那这块一加Y呢。是不是还是零。哎,所以这时候呢,我们Y呢是零,Z呢是。一是吧,哎,这是一好,这个执行完以后呢,再跑到这儿来。这是一,Y是零,再加上一个,先加加。二所以呢,结果是三。就这样啊。好,稍微有点迷糊的,下来呢,再走一下啊。哎,捋一下这个过程。好,接着我们再看下边这个啊。啊,下边这个这个看着有点。有点儿酸爽是吧?啊,这个呢叫贝斯啊,下边呢叫。啊,它的子类啊。啊,这个还得。这样一下啊。
39:00
嗯,放在这儿。嗯。啊,在上面呢啊。啊,这块这样写的啊,所以现在的话呢,我们去new一个这个sub,相当于就是造他的一个对象。哎,问这个过程的一个情况,这个题呢,每个都不一样啊,你看一看。呃,咱们直接这样说吧,要不这块呢,大家容易迷糊了,咱们直接拿着这个结果呢,咱们去匹配啊。说哪儿这就简单了,说这我也会是吧。对,我记得上高中的时候呢,尤其是上那个英语课哈,这个我们那个英语老师当年是刚毕业的。大家呢,下边就老是豆类老师啊,就说老师这个题为什么选A呢。老师就在咔咔一顿分析说啊,这个是因为这个,然后他自己来一句说老师这个我看错了,这个选B是吧。嗯,啊对,就恶心老恶心老师的是吧。诶,这个呢,由接过往回翻,确实有时候是。比较清楚的是吧,嗯,好,这块我们就直接来看了哈,我去new一个sub哈。
40:04
你为啥不就这吗?呃,你有一个sub,就他你先看看有没有静态的,这也没有静态,没静态的都还好啊,这是首先呢,你先加载base,再加载sub,但这块没有静态的就不涉及到执行了啊。好,那你这时候只需要考虑非静态代板块和构造器了。哎,他一上来呢,就掉super.method。注意,先别着急,这有个虚若空。所以呢,应该是先执行的这个是吧。你看先执行他,在执行他之前的话呢,是不是就得是先要这个了。啊,因为呢,这个非静载板块要早于构造器,所以呢,先输出的是贝斯。哎,输出了好,他输出以后呢,这个要执行它了。执行他的时候呢,叫method,这写了个100。那这个ma呢,看似说,诶这不就这个吗。大家注意啊,我们在这个之前呢,这个贝里加载了,萨类也加载了。加载的时候呢,我们这个方法呢,叫对这个方法的一个重写,实际上呢,这个方法就已经覆盖了这个方法了。
41:04
所以说这块呢,我们调这这个base里边调ma的时候呢,注意这时候你一定要小心说这不就近吗?这就不就近了啊,它就近我们提到过,其实都是些变量就近了是吧,因为变量没有覆盖指数嘛,这个时候这个method一定就是这个重写的了。这个要小心一点,或者换句话说啊,我们这个前面呢,没有写东西那么省略的就是。他也不是静态的啊,只要不是静态的省略就都是Z。那你这个这叫当前对象,这个对象就一个就是你new的。这个对象。那我这个对象呢,我这次我是不是已经都覆盖你这个覆列方法了,所以呢,自然而然就一定是我们这个子类的方法,所以呢,你接下来你会看到呢,它显示的叫萨冒号,诶你这传的100,那这就是100。诶这个一定要小心啊好,那关于傅雷的这俩执行完以后呢,我们蹦到子类这块,子类这块的话呢,诶就相当于刚才那个所谓的这个苏空呢,就执行完了,按说呢该输入它了,但别忘了先在执行那个非静态的啊,所以S呢出来了。
42:05
S出来以后呢,我们再走,这这个呢,它明确写的是修复点。那就别往这儿找了,直接呢就找负类的这个,诶诶在这儿呢,哎,就找这个方法了,所以呢,这块呢就叫贝斯了。哎,这个是70,如果这个位置没有super呢。没有修呢,肯定就是少了,是不是就相当于是你这个了。对他这块写修复呢,表明呢,他就是想调被重写的这个啊。哎,所以呢,这道题就是这样的。就是我们只要讲完这个代码块之后呢,像类似的这些问题呢,呃,大家呢,其实都有能力去做,当然这块呢,做的时候呢,一定要非常的小心,基本上我这列的这几种情况呢,就比较有代表性,顶多呢,你在见到的是比他们更恶心的是相当于这些里边的这个组合了啊。OK啊,这个当然了,做完这几道题我觉得也就够了,你要特别想去做呢,你看一下我们给大家发的这个资料呢,是不是还有一个。
43:03
哎,拓展练习嘛,是吧,这里边儿呢,有一些相关的题目啊,愿意做呢,你就做一做,找找感觉也行是吧,有助于呢,你去理解整个这个类的加载过程啊。好,这个呢,关于我们这个课后练习题呢,我们就说到这儿。
我来说两句