00:00
好,那这个说清楚之后呢,咱们下边来看一下这个CL1尼的这个方法,在什么情况下呢,这个张二编译器就不帮我们去生成了。那大家知道呢,我们初始化环节呢,主要做的事儿就是给咱们当前这个类的静态的字段呢,做一些这个显示的赋值,对吧,那么这个显示的赋值呢,涉及到代码的执行,这个代码呢,我们就封装在了CL这个类构造体方法当中。那如果不把我们去生成CR这个方法,那就意味着呢,我们就不会给当前这个类中的静态的字段呢进行赋值了,那我们看看都有哪些场景呢,会出现这样的这个问题,对吧?哪些场景呢,我们就不去生成CR了,行,那这块呢,我们专门呢再去写个代码来说明一下这个问题。以是乃ization它的一个词,OK。好,这块呢,我们主要来去说明一下哪些场景下。
01:03
那哪些场景下呢,我们说Java编译器。编译器就不会,嗯,生成啊share in it啊,这个构造器类构造器方法是吧,好,那下边呢,我们就依次呢来举例,首先说一下这个叫场景一。场景一,那这里边儿呢,关于我们这个字段的话,咱就统一的声明成public了,那实际上跟这个权限的大小呢,没有关系啊,这儿呢,我就统一的写成public,那第一个场景呢,这里边儿涉及到的这个字段啊,就是非静态的。比如我定一个int型的啊,我叫个number,不管呢,你显示的复制也好,还是不复制也好,那此时这种场景都不会去生成c in。啊,因为这时候呢,大家注意咱们讲的是不是类中这个静态的字段,对吧,那我们也称为呢,叫做类变量。而这种呃,没有加代这个修饰呢,咱们通常称为呢,叫实例变量,那实例变量是随着对象的创建,我们在对空间才开辟空间来给它做一个赋值的,对吧,所以这种场景不会去生成,那这里边儿我们做一个re compel。
02:13
哎,这儿呢,我们做一个这个编译,编译完之后呢,我们这块呢,来查看一下,哎受。OK,这时候我们打开这个method,然后这时候大家会发现没有CL对吧,这就我们说的这个场景一对对于。嗯,非静态的这个字段,不管是否进行了显示赋值啊,都不会啊生成哎,这个CD的这个方法。好,这呢是我们说的这个叫情况一,然后接着呢,我们看一下这个,哎,场景二,场景二的话呢,这当然呢,就涉及到我们这个就是得有一个代里了。行,那加上static之后呢,注意这时候我们比如还是个int型的,我呢叫成一个叫NUMBER1,但是这时候呢,我们有显示的去赋值,那此时的话呢,我们再做一个编译。
03:08
在这呢,我们直接做个刷新就可以了,那从这个字段这块呢,能看到有个NUMBER1,但是呢,我们方画里边呢,也没有这个CL对吧?这呢就是我们说的这个场景二这个静态的字段。哎,没有显示的负值,那这个时候呢,也不会啊生成。C2引力的这个方法,好,这呢是我们说这个场景二,然后接下来呢,我们说一下这个叫场景三,场景三的话呢,那我们这时候呢,是不是就涉及到要进行一个显示的赋值了,给我写成讲NUMBER2,比如来个一这种场景呢,也是说也是咱们讲过的典型的是不是生成C阶这个方法的这种场景啊。我们这块呢,做一个编译。那编译完之后呢,我们这块做个刷新,好这时候大家就看到了CR的这样一个构造器方法,然后code里边呢,就涉及到我们给这个NUMBER2呢做了一个赋值,那这个赋值呢,就是一啊,针对的就是我们这个叫NUMBER2,往这边转一下NUMBER2对吧?好这是没问题的,这个呢是咱们生成的这种场景,但是呢,现在我给他加上了一个final去修饰。
04:13
那就表示我们当前的这个变量呢,其实就已经不是变量了,是一个常量对吧,那通常呢,加上这个翻正修饰的,一般咱们把它呢,就写成一个大写了,当然这块我就暂时就先不改它了,我们此时呢再去做一个编译。编译完以后呢,这块大家做个刷新,那你会发现呢,这个CR就也没有了。对吧,就也没有了,那这个问题的话呢,咱们在前面的讲到关于这个链接的时候,在准备环节,咱们是不是专门来提到这个问题了,对吧,在这个准备环节呢,按说呢,那咱们再回到这块看也行啊。在这个准备环节,咱们说也涉及到了关于这个类中静态字段的一个赋值,但是准备环节呢,我们说这是一个叫什么默认赋值。就是默认呢,我们根据各种数据类型呢,给它赋一个值,而我们这里边呢,这个initialization初始化阶段呢,涉及到这个叫CL,那in it这个方法,而这个方法呢,它里边涉及到了叫显示的赋值,当然呢,也包括我们说静态代码块中的这个赋值了,对吧,是一个默认一个显示,但是呢,我们说如果你要是这个静态字段呢,加了一个final修饰,当然这个细节挺多的啊,咱们泛泛的一说呢,就是当你加了final修饰之后呢,显示如果复合值,这个值呢,不是在这儿做的,而是呢,就是诶这个在我们的准备环节去实现的。
05:34
也就是我们在这里边说的,你要加上这个final修饰的话呢,咱们像基本数据类型的变量呢,就在准备环节进行了一个显示复制啊,OK,回过来咱们把这种场景下描场景描述一下,这个呢,就是呃,咱们这加个比如吧,对于啊,声明为。生命为叫static final的基本数据类型。
06:01
的这个字段啊,不管是否啊,这个跟上面的一样进行了显示赋值,都不会去生成CL1的这样一个方法。啊,就是这块呢,你看我都已经显示负上值了,它不会生成这个加入的方法,那我们要把这个一去掉了,那那更没有理由去赋值了,对吧?行这呢,就我们说的典型的这个场景,当然针对这个场景三的话呢,那实际上我们关于这个static和final搭配使用这块还可以谈的更细致一些,那这里边呢,咱们就专门呢给大家呢,再写个代码来彻底的把这个问题呢说清楚,好,那这块呢,我再写一个叫。啊,以。来C选的一个TEST2。行,那这里边呢,咱们重点来强调一下,就是说那使用static final来修饰的,因为咱们重点呢,说的就是他俩对吧,使用static final来修饰的字段呢,到底是在准备阶段做了一个显示赋值呢,还是在我们的这个呃,初始化阶段进行显示这个进行操作赋值呢?哎,这是我们说的这个问题啊,这是来做一个说明。
07:07
这个使用。Static啊,加上。这个final是吧,哎,修饰的这个字段。嗯,这个负值。或者说修饰这个字段的一个显示赋值的这个操作一个到底。啊是在哪个阶段啊进行的复值对吧,那这个是我们关心的问题,那有哪种情况呢?这个我们说这个情况一呢,是在叫链接阶段的准备环节preparation对吧,这个赋值,那这是一个,然后情况二。就是我们说的在初始化阶段啊,这个复值这个呢,咱们主要是说的这叫显示复制的问题,好,那咱们把这个问题呢,给大家做一个解释,嗯,这里边的话呢,我们有几行这个写好的代码,当然这个代码的话,我们还要进行一个,呃,这个反复的去给大家做一个修改测试啊,先把这几个简单的,我们先把它粘过来,比较有代表性的。
08:12
好,那这里边呢,我们就分别呢,来进行一个说明,呃,这个重点强调的是这个sta这个加上final修修饰的,对吧,那这块呢,我们也出现了没有加final去修饰的,那这呢就相当于是比较清晰的这个场景的,来咱们做一个说明。首先的话呢,大家先看这第一组啊,当然了,你看这里边清一色的我是不是都加上static了,那不加static呢?咱们刚才在第一个例子已经提到了不加磁带这个非静态的,那显然呢,是不是呃,不会生成我们对应的CR的这个方法了,对吧?啊那更何谈呢,说在这里边进行赋值了呢,那下边呢,我们来看一下,这里边首先呢,全都是死在这个修饰了,然后呢,我们关注的就是这个final修饰不修饰的问题,这呢也是我们比较关心的一点,首先的话,我们看这个场这个场景,这里边呢,我们是咱先把这个呢,比如说先都注释一下是吧,这里边的话呢,我们没有用这个final去修饰,这个呢,用final修饰了。
09:09
那那当然了,这个咱们刚才其实已经重点说的就是它,它呢是不是应该在我们初始化阶段,这个我就把这个也补充上吧,CR in是吧。中复值这个呢,是比较典型的了,不用多说了,而对于我们这个场景呢,刚才是不是也提到了,当你加上final以后啊,对于基本数据类型的这个呢,也是在我们的,呃,这个就是在我们的这个叫什么准备环节进行复制的,对吧。好,那这两个呢,我们先做一个执行。编译。来这块呢,我们做一个view展示。啊,这块这块呢,我们看一下这个C的这个code在这里边的话呢,你会发现呢,只是针对了我们这个A来进行了一个复值,对吧?来针对它进行复值,下边这就没有,那下边的没有,我们再从另外一个维度来看呢,在咱们属性这块呢,针对于这个常量,我们有一个叫content value。
10:06
啊,就是一个常量的这样的一个属性,那这个属性里边呢,就提到了,我们会附一个值,这个值呢,那就是十是吧,它这个值是十,所以呢,看属性也行,看我们下边这个CR的这个code里边的这个代码执行也可以。好,这是我们证明的这个事情,然后下边呢,咱们再来看的话呢,嗯,那先来看这一组吧。先来看这一组,这一组的话呢,大家注意,我此时呢,是换成了叫引用数据类型叫做对吧,那上边这个呢,是加了final,下边这个是没有加final。那没有加final的话呢,这个大家应该都比较清楚,它呢怎么着啊。他是不是应该在咱们说的这个CR的这个环节才进行一个复值啊,对吧,那关键的就是大家看这块。这块的话呢,按说按说对吧,我们这块呢,是一个死在这个加上翻译中了,那按说呢,是不是也应该在咱们的这个准备环节进行赋值呢?哎,咱们跑一下就知道了。
11:07
这时我们直接在这做一个这个刷新。好做一个刷新啊,那刷新完以后这时候呢,咱们直接看一下这个扣的就行,那一方面呢,还是我们这个A赋值为一的这个事情,另外呢,你看这有一个100的问题。往这边拽一下是吧,100的问题的话呢,你会发现哦,诶这是加上final的这个100这块呢,也是做了一个啊in sta这个我我们因为呢调用了这个叫value of啊下边呢,是做了一个赋值对吧?哎,做了一个具体这样一个赋值,然后呢,在下边呢,是涉及到我们这个1000了,言外之意呢,就是我们会看到下边的这两个,不管你是不是一个常量。它都是在咱们的这个cell in,也就是说初始化环节进行复制的,你看上面这个field的话呢,也能看到它俩是不是就没有像这个in constant一样,有一个constant value了,它俩都没有,那IG呢,就是我们这两个情况呢,是不是都应该是在哎叫初始化这个阶段进行复制的呀?
12:09
对吧,哎,都是在这个初始化阶段进行复制的,那这个呢,是不是我们可以总结一下呢?叫什么呢?说像这呢,咱们叫基本数据类型,我以int为代表的基本数据类型的话呢,我们要是进行了一个显示的赋值,然后呢,你加上final了,我们就在准备阶段是吧,你要是没有加final呢,那就在这个初始化阶段。对于引用数据类型的话呢,说诶不管你加不加final说都应该是在这个初始化阶段,目前的这个结论呢。那是这样是没问题的,对吧,那现在呢,大家你看一下,你刚才不是说已用数据类型的话呢,应该加不加反轴,都是在这个初始化阶段吗?看看是不是这样子的呢?哎,我这块呢,比如再补一个public。Static。哎,我这里加个final对吧,我也加上final了,String类型的一个S,那这块我们比如说叫S0下边这叫S1啊,然后它这块呢,我直接呢,就写了一个hello word。
13:08
跟下边这个不一样,下边这个是个new的行,那针对这两个问题,我们也在做一个编译。嗯。编译完以后呢,我们这块再做个刷新,好大家呢,其实也基本上看出来这个场景了,我们看属性的话呢,你会发现呢,这个in constant跟我们这个S0,你看它都有这个constant value,那杨I呢,就是这两个哥们呢,应该是在准备阶段负的值,那我们看下这个方法呢,是不是也可以同样的来做个验证。在这里边这个,呃,这个100啊十啊,这是咱们刚才说的这两个场景,然后再往下走。那再往下走的话呢,其实就到这儿了啊,这个new dump l DC hello word这块,大家看hello word可能会有人会怀疑是他哈,其实呢是下边这个,因为咱们这块的new的话呢,是new个对象,下边这块呢才涉及到new对象或者这块,以防大家呢晕,我这呢我写个hello word0这呢我直接写个hello word1,这样咱们俩做个区分。
14:07
那这个我们再做个刷新,那这就清楚了,咱们这块呢,实际上呢,是针对的是这个new的方式,在这个C2当中做的执行,而这个直接复制的这个字面量的方式呢,是没有出现的。对吧,哎,没有出现的,那针对于这种场景呢,咱们又是在这个准备环节。实现的是吧,而这个呢,是不是在这个CR当中去实现的呀。OK吧,那按照咱们目前这个情况呢,咱们是不是可以呃总结出来一个小的这个结论,大家来看一下,就是我们在什么情况下,它是在链接阶段的准备环节去赋值的呢?对吧,要想是在链接阶段的准备环节赋值。这个情况那都有哪些呢?首先的话呢,我们是不是一定要加上一个final吧。
15:00
对吧,你要加上final不加final的这个没得没得选,那你肯定是在这个准备阶段,在这个初始化阶段进行复制的,那首先呢,第一个前提是得有final,那有了final就一定是在准备环节吗?发现呢也不一定,那这个就不是这个是不是也不是啊。但是基本数据类型这个我们目前看到是不是都是对吧,那这个我们先这样写,首先第一个呢,说对于基本数据类型的字段来说啊,这个如果使用static。啊,在这个final去修饰啊,则这个通常是在这个我们说链接阶段的准备环节复制的是吧。OK吧,就是我们基本熟悉类型呢,你看这个使用static final去修饰,然后呢,这个显示赋值了,那这时候呢,你是在这个链接阶段这个准备环节进行赋值的。啊,使用带这个修饰,嗯,我们这个也加上使用在这个修饰并显示赋值是吧?哎,或者这样说吧,则这个显示赋值。
16:09
哎,通常呢,是在链接阶段的这个准备环节进行好,这呢是我们说的这种情况,然后第二种情况呢,我们说这里边儿呢,刚才看到有这样的一个特殊情况,除了基本数据类型之外呢,我们这还有一个引用数据类型,谁呢,就是关于这个string,因为string啊比较特别,因为它除了呢,咱们使用new的方式做一个类类型,它除了用new的方式去实例化之外呢,它呢还可以使用这种字面量的方式去做一个赋值。所以第二种情况呢,我们说就对于这个死追来说。啊说如果使用字面量的这个方式赋值啊,使用static final修饰的话。那也是则这个显示复制操作呢,是在链接阶段这个准备环节进行的,那只要呢,你这个没有使用这个final去修饰,那就不用多讲了,那肯定呢,是不是考虑应该在咱们的这个初始化环节进行啊,那也就是这样的问题,比如说我们这呢叫static,这呢我叫string s2,这个咱们写个叫hello word1word hello2对吧,像这个问题我们在这再做一个re compel。
17:24
就没有加final的这个场景呢,大家就不用多想了。那这块是不是就多了一个哈。诶,Hello word2对吧,你看上边你看这个属性,这个时候呢,关于它这块也不会说出现一个叫value了。OK的对吧,也就是呢,没有加这个final的,那不用多想,没有加final的话呢,肯定是不是应该在,就是你显示复制在我们初始化环节进行,对吧,咱们现在主要讨论的就是加上final以后,这个哪些情况呢?是在这个准备环节哪些呢?还是在人家的初始化环节。啊OK,那就目前呢,我们看到这个情况来讲的话呢,这个在。
18:01
这个初始化环节进行赋值的这个情况。这个情况呢,似乎呢,就是是不是就是排除上述的这个在准备环节,哎赋值的情况,哎之外的这个情况,这个有点绕是吧,就只要你不是这两种,那正常的都是在我们的这个初始化环节CR这里边进行实现的。哎,你看我刚才说这个话呢,这个大家可能发现其中有一些词汇很奇怪啊,说的是,呃,似乎呢是我们除了上面这两个情况之外呢,就是在这儿了,好像说诶难道还有点问题吗?那其实关于这块啊,可以谈的事情还挺多的。还挺多的,实际上呢,中级的这个解释的话呢,呃,大家呢,嗯,就是来看的话,其实也不是这个啊,就是你看很多的这个书啊帖子呀,乃至于说有一些人讲的这个视频当中,其实关于这块描述呢,说的是比较含糊,或者说呢,严格上来讲是不对的。
19:04
啊是怎么讲的呢,这个通常呢,关于这个呃,准备环节赋值和初始化环节赋值的时候呢,一般我看到书上都是这样来写的,说如果你当前这个静态的字段。不是静态的,咱们就没得说了啊,这这那都是这个使用环节才出现的,你这个静态的字段呢,说如果要是用final种修饰了,那么就应该是在这个准备环节呢进行显示赋,如果没有用final修饰呢,就是在我们这个初始化环节进行赋值,这个大家目前来看是不是肯定这个结论就错了吧?因为呢,咱们看到了像这样的场景,像这样的场景是不是仍然是在咱们初始化环节进行复制的,对吧?啊OK,那其实我这里边儿呢,还有一个点说的不准确。啊,有的人说这这刚这个还没整明白呢,怎么又变化了呢,大家你看啊,我再给大家写个例子,我这呢叫一个NUMBER1吧,哎,右边大家注意,我现在呢,是在这个final修饰的一个int型的变量,假设呢,我这写成是一个二。
20:04
那么问大家这呢在哪负值啊,就是这个二的这个值。是不是很显然,他应该是在咱们这个准备环节进行复制啊。编译。啊,这个其实我们都不用测了,对吧,但是我们这个稍微也看一眼啊,刷新这时候呢,你看我们这个NUMBER1,诶在这儿是在我们的这个准备环节负的值,你去这块找这个CL in这个code里边,你也不会找到我们这个NUMBER1的这个身影,那它最后这块呢,就说到这个hello hello word2了,对吧,那跟针对这个S2后边呢,就没有了。所以呢,这个呢,就是在咱们的准备环节赋值的,但是这个大家注意,我这二呢,我不是在这写的二了,我怎么着处理啊,大家注意啊,我写了一个叫new的一个random。这个大家应该都知道,就是我们举你有个随机数是吧,然后next int,比如我这呢写个十。我们这个印着型的常量的赋值啊,我不是直接显示负了一个数,而是呢,通过一个方法的调用实现了一个负值,那么这个呢。
21:06
大家觉得此时他应该在哪赋值啊?这个显示的赋值。嗯,你就这样想吧,我们在这个编译之后啊,咱们把它加载的时候呢,这个数能不能确定下来。嗯,那事实上呢,是不是确定不下来,那这呢,其实就是一个具体的操作了,你需要创建一个对象,开辟内存空间,调它的方法,所以说这个呢,诶需要有相应的代码的支持,不是一个简单的赋值操作了,类似于咱们上边这块呢,你看出现new的这样的一些操作,所以这块呢,我们需要相应的一些指令的支持,言外之意。大家这时候你看你刷新一下,我们再去看上边,比如说从属性这块来看,关于NUMBER1,它就没有这个这个constant value这样一个属性了,对吧,不像我们上面说的这个了,另外一个角度呢,就是我们下边看这个C2的这个code里边的时候,大家呢,你会在这儿也发现在你这个S2呢,搞定之后,那下边呢,是不是增加了我们关于reyme的一个实例化,包括呢,我们这个next in的方法的调用啊,包括给我们这个纳一赋值的操作,就整个呢是这几行。
22:12
那这块呢,就证明了,其实此时的它就应该是不是又在初始化阶段进行复制了。对吧,那要是这样来讲的话呢,你看我上边写的这句话,严格上来说这个也不对,你看我这咋写的说对于基本数据类型的字段来讲,使用这个修饰的,那显示赋值呢,就应该是在准备环节进行,呃,那这个呢,你看显示赋值你怎么看了,我把这种咱可以理解成呢,叫显示赋值,这个的话呢,按说也叫显示赋值是吧,但是它呢,又是在初始化环节进行,所以说呢,由这个呢,咱们相当于呢,在呃这个往前往往往后再推一步,就是这个你显示赋值呢,咱们不涉及到你这个。叫什么呀,对象的创建,在运行环节需要动态的去复制的场景啊,所以这个呢,显示赋值咱明确一下啊,是不包括。
23:03
哎,就是或者说我们这个显示数呢,就直接负负这个常量的这个方式。复制常量是吧,而非调用啊这个方法啊,这样的这个方式,那大家要注意一下这个场景,那具体细节的话呢,其实我们这块呢,大家可以呃,从我们刚才讲的这个里边呢,抽取出来一个,呃,什么样的问题呢?就是说只要是我们首先呢,你得是在这个final译修饰的对吧,就是我们只是说苛刻的这个准备环节进行复制的这个场景啊,首先呢,你得用在这个修饰。其次的话呢,呃,基本数据类型的话呢,你这块呢,都得是确定的值,你像这你不确定的,那不行是确定值啊,这呢都是在准备环节,或者的话呢,你像这个string比较特别,因为它呢可以通过自变量的方式去复制,这个呢也是在准备环节做的,除此之外,你像引用数据类型,咱们通常你要实例化的时候去赋值的时候呢,要么是这种调方法的方式,要么是这种new的方式啊,包括像这种基本数类型啊,有调方法的方式,只要涉及到方法的调用,乃至于说构造器的调用,那这个时候呢,都需要代码的支持,那你就都要在cell这个构造器方法当中去实现。
24:19
啊,这是咱们最终的这个结论。啊,最终的这个结论啊,这个在这也可以简单说一下啊,最终结论呢,其是这样的,这个呢,其实是比较准确的啊这个大家呢,你也看到我通过刚才这个测试呢,就得出这样的事情了,那如果说你想这个呃叫什么?转一下的话是吧,你在面试的时候,或者在跟别人去谈论关于这个显示赋值的问题的时候呢,你把这个结论抛出来,那很多人这块呢,他们其实是啊,不理解的是吧,不是不能叫不理解了,就是他们一开始想不到,哎,最终的结论其实是这样子的,对吧,就是什么结论呢?哎。使用。Static。啊,加上final修饰的修饰啊,然后且这个赋值啊,且这个怎么说呢,使用static final修饰。
25:12
而且这个显示负值中不涉及。嗯,不涉及到啊,这个方法或构造器调用的。啊,基本数据类型,哎,或这个词论类型。的这个显示赋值,那是在咱们说的这个,哎,这个链接的准备环节进行的。那你看这个呢,是不是就我们说的最终结论再说一遍啊,使用代这个final修饰,那你要没有final修饰,那那就是在。初始化阶段对吧,使用指甲修饰,并且呢,显示复制当中不涉及到方法或者构造器的调用。
26:01
啊像像比如说像类似这种啊,像像这种啊啊像这种啊是吧,那你都得是在这个准备环节,这个初始化环节进行了啊,而我们这个呃,不涉及到这种调用,而是直接字面量的方式,这样负的值的这种方式,基本数据类型或者string方式,除了它俩之外呢,别的也不会说你直接呢去赋个值啊对吧?哎他们呢,这两种情况,哎,他们才可能是在准备环节进行,除此之外呢,哎,都是在咱们初始化环节进行。啊,这块呢有点难,哎,大家呢,这块呢捋一捋。
我来说两句