00:00
行,那有了这个知识的储备之后啊,哎,我现在呢,至少敢给大家去说这个问题了,而且呢,我也比较有信心呢,能够给大家把这个事儿呢讲明白。行来咱们看这个代码。好看这个代码,这个代码的话呢,难在哪呢?就是难在呢,它在JDK不同版本中,它的执行结果呀是不一样的。啊,我们还回过去哈啊,在JDK6当中是一个结果,在GK7跟八当中是另外一个结果,那么想必呢,这个分水岭呢,大家也能够想到,就是在JDK开始七开始的时候呢,咱们string它的字符串常量池是不是放到我们堆空间当中了。那正因为这个分水理论存在,所以导致我们这个结果呢,它在不同的版本当中运行的结论呢,是不一样的。那行,咱们呢,就先来跑一下啊,先来跑一下这个结果,那首先呢,咱们把当前这个改成这个六,那在这呢,咱们调成这个六。啊,应用一下。然后呢,咱们再回到咱这个叫edit这个位置,针对于咱们当前这个叫诶string in的这个操作,咱们呢,也把它改成是个六。
01:04
好,我这块OK一下,那此时呢,我们做一个执行。好,这个结果呢,已经比较清楚了,就是false和false,那我在这标识一下啊,JDK6的时候呢,这是false。啊,这个也一样。嗯,没问题,行,那么接下来呢,我把它改成JDK7,当然了,我们改成七改成八是一样的。啊,因为从七以后的这个版本呢,答案呢全是一样,这呢我就不一个个版本去演示了,没必要对吧,我就写成这个七啊演示这个分水岭。此时呢,再去执行。好,此时呢,我们看这个结果呢,叫做false处,放在八里边呢,也是false处,嗯,也就是说呢,我们上边这个呢,JDK6也好,JK78也好,他们其实这个结果呢,都是一样子的啊,这个我们也写一下吧,CTRLC一下啊放到这啊,CTRLV这个呢,我写一个七,写一个八啊为什么把八呢有特意强调一下,因为八呢改成叫圆空间了,改成圆空间之后呢,咱们字符串常量池也没有放回到圆空间,还是在堆里边的啊,所以我把八呢也带上,这呢都是false,那么针对于咱们下边这个情况呢,就不一样了,这个呢就改成了是叫处。
02:16
对吧,这是我们刚才运行的这个结论,行,那下面呢,咱们来解释一下,那解释的话呢,诶,因为上面这个呢,你看它都是false啊,其实这个呢,相对来说解释起来呢就比较容易,关键就是难就难在这儿了,那咱们先看上边这个。啊,为什么上边这个呢,它都是false,看一下我这块呢new string,因为咱们刚才呢,已经说了这个new string到底招了几个对象了,返回来到底是什么,所以我们这会再看是不是大家就非常有底气了,我new哥string呢,诶就就按咱们这个代码这个执行的效果来看,前面没有任何代码,咱们是不是造了俩对象一个呢,叫堆空间中的一个一。对空严中造谣对象对吧,它是个一,然后另外呢,是不是字符串常量池里边还有一个一啊,那至于说你这个字符串常量池到底是在JDK6当中的这个叫永久带呢,还是在JDK7跟八中的这个,嗯。
03:04
哎,左耳长呢,只放在这个,对空间中呢,无所谓。无所谓对吧,反正我返回的是对空间中的那个对象。啊,就是咱们刚才那会儿其实说到的啊,你这不是造俩对象嘛,咱们这个返回的实际上是这个对象是吧?好,这是说的这个S啊,然后s.inter这个in inter的话呢,咱们刚才那会儿呢,也稍微的提到了一下它,那它呢是会去这个字符串常量池里边是不是去找,是不是存在一啊,那么问一下大家这个string s点的in inter,咱们在这个常量池里边有没有现成的一啊?显然是不是有啊。显然是不是有啊,对吧啊,因为在GDP不同版本中,它这个结果都是一样,咱们现在是不是调到这个七里边了哈,我这块呢,就先编译,这不用编译了,因为已经跑过了是吧,我们直接呢,就开始这个磁金码指令。啊,这我刷新一下,咱们看一下这个main方法。啊,点开大家看啊,这块呢是我们new的这个string,然后这块呢,是不是放了个一,然后呢,接下来你这块呢,叫s.inter啊inter的话呢,其实啊这个这是保存到这里啊,这又加载了一个一,其实这个一的话呢,是实际上我们下边这个操作是吧,就是这个in的方法呢,其实就是还是放到我们这个组常量池,但是常量池里边已经有这个一了。
04:15
能理解对吧,哎,所以这块呢,我们,哎这个可以大家更透彻的去理解的话呢,就是呃,调用此方法其实没有太大的作用啊,就是调用此方法之前。哎,这个字符串常量池中已经存在了一。啊已经啊存在了这个一行,那我们接下来这个S2呢,这个又是一,这个一呢,实际上就是从咱们第一开始,你用这个对象放到长按里边那个一的一个地址。啊,那这俩地址显然不是一个地址嘛,一个是你对空间中你用的这个对象的地址,一个呢是你常量池里边这个对象的地址,那显然不是同个对象嘛,所以这两个都是false。还行是吧,哎,这个呢比较清楚,那如果呢,大家要看这个图示的话呢,你可以看我这儿画的这个S跟这个S2呢,就是一个呢是指向咱们堆里边牛的这个对象,一个呢是指向常量池的,这个常量池我们是在六中呢,就是这个永久带是吧,你要放在这个这对期的时候呢,哎,这个也叫永久带,但是我们不在这放了,放在这个对空间里边了,那此时这个S2呢,指的还是你这个的地址,但是你这个呢S呢指的是这个地址,咱俩地址呢是截然不同的。
05:26
对吧,这个针对于S和S1呢,这两个呢,应该说基本上所有的人呢,我想都能答对啊,答错呢可能概率都很小啊,然后关键的就是下边这个答对的概率呢就很小了,来剖析一下。我们这块呢,New new刚才呢,是不是咱们恰好把这个问题呢,已经说的非常透彻了。对吧,哎,这我说的已经很透彻了,行,那么这个你完之后,我们这个叫S3啊,那么此时这个S3的这个地址。那这我写一下。嗯,因为咱们说这个引用类型的变量,它这个保存的实际上都是一个地址对吧,看reference,那它这个地址啊,记住的是啊,或者这个变量啊。
06:07
那记录的这个地址为什么呀,就是咱们实际上是不是相当于是new了个顿,里边呢,是写了个一一啊。就是对堆空间中你用了个对象,这个对象的内容呢是叫一一是把这个地址值给了我们这个S3了。给了这个S3了行,那么这行代码执行完以后,我问大家一个重点的问题,我们字符串常量池当中是否存在意义呢?我这写一下执行完。啊,这个上一行代码以后。嗯,字符串常量持重。哎,是否存在啊,这个一呢。这个呢,跟咱们这这个版本啊没有关系。啊,就是上行这个代码跟GB版本没有关系,有没有意义,大家回忆一下,咱们刚才在这是不是我讲的很清楚了。
07:05
咱们就是演示它的这个在字符串常量池有有吗?你看我这个说过是不是没有,这个叫AB,那在咱们这儿呢,是不是常量池中不存在这个意义啊。诶不存在,行不存在,那么接下来呢,我们通过这个S3.1的方法,那此时呢,我们是是不是就是在字符串常量池中。哎,是不是呢,去保留保存,哎或者应该叫叫生成吧,哎,生成是不是叫一一呀。能理解对吧,哎,生成这个一,然后下边的我们这个string s4这个S的这个一是不是就使得咱们上一行代码呢?字符串常量池生成生成的这个E1的地址啊,哎,这个咱们这先写一下啊,就是它呢是诶使用的是这个上一行代码。啊,操作时或叫执行时,哎,在常量池中。
08:02
哎,这个,哎,生成的这个。一一的地址。哎,或者这个,哎,我们说S4,哎这个变量啊,记录的地址。对吧,诶它记录地址呢,使用的是上一行这个代码呢,执行完以后呢,我们长远池里边就有意义了。啊,然后这块呢,它记录的就是你那个常量池那个一一的一个地址,对吧,这呢是我们S4,那这个S4呢,记录的是这个它的地址,那这个地址跟我们S3,诶说这两个哥们儿,他怎么可能还是处呢。对吧,诶大家呢,可能答错呢,就是因为可能都会选成是false哈,它呢记录的是诶字符串常量池中这个意义的地址,你这个呢,记录的是new润的地址,八竿子打不着,怎么这块你就成了一个触,呃,这个可能还是触呢。哎,那这个问题呢,实际上呢,哎,主要呢,是在这个,主要是在这儿。哎,说主要是在这儿,在字符串常量池当中生成这个一。
09:01
生成一一了没问题,但是呢,这个一一的话呢,呃,这个其实我们重点讲解的就是它哈,这个一一呢,我们怎么来理解这个呢?我们说啊如何理解。这个理解呢是不一样的,在这个JDK6当中。啊,在GT6当中如何举例子呢?就是我们创建了一个,哎,创建了一个。哎,新的对象,哎,这个对象呢叫一啊,那么既然是个新的对象,是不是它就会有一个新的地址啊。哎,创建了一个新的对象,那么也就有哎新的地址。所以说呢,咱们在这个GT6当中啊,你会发现这个地址跟我们这个地址呢,显然是不一样的。这呢是咱们JDK6的一个解释方式,好,那么在JDK7当中啊,这个我再往下啊。
10:00
嗯,在这写啊,这这个7JD个七呢,它有一个变化,就是呢,我们把这个常量池呢,放到这个堆空间当中了,就这是堆,大家注意这是堆,然后呢,咱们在这呢,是不是new了个对象,那new的这个对象呢,你的实体内容是不是就叫一一啊哎家就是这个一个对象,好这呢是咱们这个字符串常量池,大家注意啊,现在有变化了,JDK6的时候呢,就是我们在这呢,实打实的放了一个对象,这个对象呢就叫一一,所以这个地址。跟咱们这个new的地址显然不是一个啊,这是JDK6的,诶我我其实也不应该在这画了,因为JDK6根本就不会是不是在我们这个对空间里了是吧?看你在这个永纽带里边啊行,那这块呢,我说成这个就是在这写一个吧,啊这是J个六是吧,这俩地址不一样,那在JDK7的时候呢,它会这样了,因为呢,你把这个自串常量池啊,你放到这个堆空间里的,那这时候呢,我们还想考虑这个空间的一个节省,你这块new了一个string,这呢放了一个一一,那你这放到一,我们再调这个寸方法的时候呢,我们是不是要往常量池里边放一个呀,但这时候呢,注意我们就不再放了,因为呢,你这块已经有一个一一了,所以这块呢,我们此时的这个一一里边,它记录的是什么呀,就是咱们这个的地址。
11:08
注意哈,咱们这块呢,把它的这个地址呢,就相当于是给他了,他呢就指向他了,就这呢,其实记录的就是这个地址,所以呢,就导致咱们在这个JDK7当中,其实并没有真正的创建一个新的对象一一,而是呢哎,这个常量池中记录了咱们堆空间中你new的这个一一的一个地址。啊,这个地址,那么这个地址呢,它也呃返回来,但是没有变量去接收嘛,那那当我们下一步这个S呢是叫一一的时候,这个一一的话呢,就去常量池里边去找了,这个自变量的方式,不都得到常量池嘛,常量池一找这个一的时候呢,发现你指向的是不是谬的这个对象的一个地址啊,所以呢,此时咱们S4哎,你指向的是这呢,是咱们这个占空间,你指是S啊S呢你指向的是它,但是它呢指的是这个地址,所以呢,这个四说白了指向的是它,而S3呢,本身就是指向了它的,所以它俩的地址是一样子的。
12:01
哎,说清楚了啊,在JDK7的时候呢,我们说此时啊,这个常量池中啊,这个常量池中啊,并没有哎创建。那这个一。啊,此时常量池中并没有创建意义啊说而是呢。嗯,而是嗯,哎创建了一个指向。哎,指向啊,咱们这个堆空间中。哎,你new的这个,呃,这个对象它的一个地址。哎,这个写的有点长了,行,那么这时候呢,就导致你记这记录这个地址,哎,然后呢,你下边这个S呢,记录的就是你用的那个地址,而跟我们上边这地址其实就是一个,所以导致呢,他俩呢,其实就变成同一个地址了,那因为呢是同一个地址呢,自然而然他这就是个处。诶,我这块呢,解释完了,那不知道大家呢,有没有彻底的把这个问题呢,给他弄清楚。
13:04
啊,你看这里边呢,诶,它这个一这个引用呢,其实还是用的我们这个堆空间里边用的这个对象,那为什么要这样做呢?就是因为呢,反正大家都放在堆里边,我们这个长远池里边尽量啊节省空间,你在堆里边已经有个一了,我就直向直接指向你,那这呢就不再存这个实体数据了,就放个引用地址就完了,对吧?那你想想这个字符串,如果信息很长,我这就放个地址,地址的话呢,Reference是不是就跟int一样占四个字节是吧,就非常的节省空间嘛,所以呢,我们在这学期里边呢,就这样来进行一个设计。啊,就这样个情况。好,这个呢,咱们就解释完了,这个有点悲壮是吧。
我来说两句