00:00
那么多先生咱们就告一段落了,接着的话呢,我们来看下边这个章节,诶前面的话呢,我们说过一个事儿,说呢,这里边儿这个章节啊,基本上都是相互之间独立的,就是彼此之间呢,没有这种递进关系,就是多线程呢,如果说还有一些知识点没有整的太明白,不影响我们下边的学习。呃,说句话的意思呢,就是说我们现在也算是一个新的开始了。OK啊,那我们这一章呢,叫做长类和基础API啊,基于面向对象,我们来看这些内容。这里边儿呢,有一些呢,大家看着还是比较眼熟的,比如说。嗯,前面呢,我们在讲这个string的时候呢,提到过,说后边呢,我们针对string呢,还要专门的去说一说,诶实际上呢,就在这块呢来讲,因为呢,我们在实际开发当中,针对字符串呢,处理的场景是比较多的,那我们这儿呢,就把它呢专门呢再讲一下,那跟死针相关的呢,实际上呢是一直就到这儿了。啊,这里边儿除了string之外呢,我们还要再讲两个跟它相关的类,一个呢叫string buffer,一个呢叫string builder。
01:02
哎,这两个类整个这块呢,都可以理解成是跟字符串相关的类。这呢是我们要讲的第一波常用的API,然后另外的话呢,这块我们提到了跟日期时间相关的,大体上来讲的话呢,应该是这样的一些专题。但是这块呢,日期时间的API的话呢,首先第一个点比较多,所以我们只挑选咱们平时呢,算比较常用的一些,至于说呢,以后比如说你参与的一个项目呢,可能是像比如说携程啊是吧,这样的一些项目,他可能还不光涉及到中国,还有世界范围内的,呃,跨时区的啊,这样的一些日期时间处理,那就另当别论了啊,你再去看一看我们没有讲的一些日期时间的一篇了。那我们这里边儿呢,只讲长的一些日期时间的,但是长来讲的话呢,又分成一个分水岭,这个分水岭呢,就是JDK8。G8之前呢,就是我们上面提到的这样一些API,那么在JDK8当中呢,又引入了新的日期时间的API,那为什么要引入呢?到时候我们再讲。
02:02
所以这块呢,稍微的复杂一点,我们处在这个新旧的交替当中,所以呢,旧的呢可能会用,新的呢也可能会用,这呢是我们讲的第一波啊,第二波日期时间的一篇。然后呢,第三波呢,我们要说的就是跟对象。比较大小相关的API,这呢对应的是两个接口,一个呢叫compable接口,一个呢叫comp接口。那如果呢,我们要针对于类啊,它对应的这个实例就是对象了啊,多个对象需要比较大小,或者说呢,需要排序,那我们相应的呢,就要考虑这两个接口之一。啊,至于说呢,应该选哪个,它俩有什么区别,到时候我们再说,那其他的相关的一些API,比如说这个mass这个类的使用啊,包括呢,我们提到了这个以前呢,讲这个float double这两个精度不够高,那如果我们需要呢,处理这个精度比较高的,那我们涉及到的叫big decimal啊相关的类呢,我们就放到其他这里边了啊给大家呢去讲解一下啊打开的话呢,对应的有这样的一些是吧。
03:03
好,这呢就是咱们这一章呢,要讲解的内容跟前面的章节关系不大啊,所以这块多线场呢有些问题呢,这个下来呢再看一看,然后这块呢,没有影响啊,哎,又是一个新的开始,比如前两天跟那个女朋友吵架了啊,就不要找借口说这一章学不好了。啊,面向对象的时候吵架了,那才起作用啊。好来我们看一看啊,首先的话呢,我们要讲讲跟顿相关的一个使用了,那对应的我这个model呢,都已经创建好了,嗯,还是呢啊大家呢,你下来呢,做的话呢,就看这个Mo了,然后我这块呢,就针对于这个Mo呢,开始去做这个演示,诶首先呢,我们来看一看这个string的使用。好,这块讲这个磁针使用的话呢,诶,我倾向于呢,就以GD8GDD8为例呢来进行说明了啊,因为呢,这个底层呢,它其实会有一些变化啊,目前呢,这个JD8呢,也算是我们用的比较多的一个版本,其次的话呢,我们先以八为主,讲清楚以后呢,我们再看后续呢啊有一些什么样的变化,所以这块呢,建议大家呢,我们针对当前这个modu呢,咱们就做一个切换了。
04:06
哎,这块找到我们当前这个module,然后这个位置呢,我就把它改成是八了。OK啊,这块我也调成是八,诶同学呢,不知道这两个区别,这个我们使用的就是JDK啊,用是哪版本,我就换成八了,然后这个位置呢,指的就是我们现在这个相应的代码使用的这个语法规则,那我们也是基于八的,意味着就是九之后的API,那你就看不见了。不是有之后的这个语法你就不能使用了啊,这个意思啊。当然API的话呢,你也看不见是吧。嗯,好这呢,我选一个OK啊好,那么这时候呢,我们这里边儿呢,测试的时候呢,你就不能够去演示九以后的相关的这个新特性啊。好,然后呢,有哪些变化呢?待会我给大家去说,呃,关于string,首先的话呢,我们看一看关于这个类的一个声明啊,从这个角度呢,我们开始切入,首先呢,CTRLN这呢,我们去写入一下叫string。看一下它的说名,这呢,我们就先来看这个八了,打开。好,直接往上拽。
05:02
找到了,哎,这个在这儿呢啊。找到了他最初声明的一个位置,然后把这个呢声明啊CTRLC给他呢拿过来。他呢是这样声明的,那么通过这个声明的话呢,诶,我们来看看这里边想刻画的这个点啊,嗯,比如说这里边儿呢,我们看到它有一个呢,叫做final的一个声明。表示呢,这个string呢。对,是不可被继承的。哎,这个呢,我们就清楚了啊,有的时候这个小的比例题呢,会问说我现在想生明一个类呢,去继承一润可不可以,这个你知道不可以啊。然后呢,我们看到它呢,实现了相关的接口,没有明显的写这个负类,那意味呢,就是它是继承object的。OK,然后下边我们看到呢,它实际上的接口,首先呢,这里边有一个叫serre liable。啊,这个接口呢,翻译过来叫做可序列化的。哎,叫可序列化的这个接口啊,然后这个接口呢,它的作用是什么呢?我们后边讲到IO流的时候呢,会说凡是实现此接口的类,它的这个对象呢,就可以序列化了,什么叫序列化呢?就是可以通过网络或者是通过我们本地的这个流呢,进行数据的一个传输。
06:13
啊,简单我这块写一下啊,说凡是实现此接口的。啊类的这个对象就可以通过。哎,网络。哎,或本地这个流啊,进行数据的传输。哎,传输啊,这个呢,简单来说呢,就是相当于我们这个对象呢,竟然可以呢去传输了,这个呢,就我们后边会讲IO流里边的一个叫对象流,到时候我们会说这样的一个接口啊好,后边这个呢叫comparable comparable后边这个呢,大家没有见过这个呢,其实就是泛型啊,我们呢就先放一放,讲完集合的时候呢,我们再说这个泛型。这个comparable的话呢,其实也是我们这一章里边呢,要讲的两个接口之一,就是这个。
07:00
哎,凡是实现这个接口的对象呢,都可以比较大小。啊,凡是实现此接口的这个类。啊,其对象都可以比较大小。说白了就是在我们这个接口里边有出厂方法,然后我们瑞呢实现了这个接口里边放方法指明了,诶怎么算叫大,怎么算叫小,给了一种标准啊,其实就是重启了方法了。后边这个呢,叫插七棍子就是字符序列了啊,然后呢,字符串嘛,它实现了字符序列这样一个接口啊,这个就不多说了,这呢是我们通过这个声明呢,看到的一些情况,好接着的话呢,这里边儿提到说内部声明的属性。String的话呢,它内部呢,声明有一些属性是其中呢,我们比较感兴趣的话呢,应该是这个。哎,我们把它呢拿过来。这个话呢,叫private final类型的一个数组,它把这个号呢,写到后边了吧,哎,那么这呢,其实呢,它就是我们叫做字。
08:01
比如说你这个号的定义成啊,双引号里边呢,叫一个哈。那么本质上来讲这个哈呢,其实就是存储在我们当前这个叉型数组里边的。哎,所以说这儿呢,体现的就是我们字符串呢,真正存储数据的啊,这样的一个容器啊。啊,存储字符串啊,这个数据的这个容器。OK,那刚才呢,我写的是个哈,那其实呢,自然而然的,我们这个Y6数组呢,它的长度就是五啊,因为有五个字符,OK,然后呢,这个属性的话呢,我们看到它声明的是一个final是吧。这个final意味着。对,叫不可更改了,言外之意呢,就是我们这个Y轴呢,一旦指明了某一个数组之后呢,你是不是就不能变了。啊,这个final相当于指明。诶,此哎,Y6这个数组。啊,一旦。啊,一旦呢,这个初始化是吧。啊其啊,这个地址就不可变。
09:03
OK,说白了就算一个常量了。啊,那呢,你比如说我们这个字符串呢,我叫hello哈,然后现在呢,我想改成叫HELLO1哈。啊,那这时候怎么办。对,那这时候呢,是不是意味着呃,数组的话呢,我们说呢,你的长度呢,这时候已经是五了,你现在想变成六嘛。那不好意思了,这块我没有办法给你去加,你得新建一个,但你新建一个的话呢,注意你能在我当前的这个论的对象里边呢,用这个Y流吗。不能,因为我已经final了嘛。我已经翻出了,这我不是静态的啊,也就是说你当前这个钝的对象呢,每个对象有一个value,那你现在想指向一个新的数组,那你只能是新提供一个钝的实例。对吧。哎,那就意味着我们字符串的话呢,你看似呢说把哈呢改成哈一,实际上呢,相当于是新造了一个对象。啊,这个事儿呢,不用着急,我们后边呢还会展开来讲啊,这个呢,就是我们想给大家强调的主要的这样一个内部的属性,但是这块呢,我们要说一下这个属性的话呢,是在咱们JDK8当中的。
10:08
哎,也就是说JD8,哎及之前咱们声明的都是叫叉型的一个数组,从JDK9开始。啊,一直到我们现在啊,这个底层的这个结构呢,就变了。啊,然后这块呢,我们要直接看这个17的话呢,我就CTRL加上N,我还是string,然后我们点一下这这个呢,就是17的API了,呃,因为呢,我这块没有装九,其实呢,大家如果你要是装些九的话呢,看的会更清晰一些啊17这里边呢,明显已经看到它变成了叫BAT类型的一个数组了。其实九开始就变了啊,我们只是拿17呢这块来说的,哎,那这个呢,也是咱们存储这个字符串数据的一个容器。那么我们会看到呢,有点儿。不可接受似的是吧?啊,那这个该怎么去理解呢?
11:02
主要呢,就是把叉改成be了是吧。诶这块呢,在我们这个课件里边呢,我稍微的提了一下这个事儿哈,就是G8里边这个源码,然后呢,在这个GDK9的时候呢,就改成这样的一个结构了。哎,这呢是官方有一个相关的说明啊,它呢是这样解释的啊,说呢我们会发现呢,实际上这个string的这种对象,咱们在内存当中去存的,大部分的这个场景下呢,是不是就the most是吧,大部分的这种死令的对象呢,他们只包含的是拉丁的这些字符。哎,拉丁字符,这个拉丁的字符的话呢,其实他们只需要呢一个BA呢就可以存储了。啊,这个大家可能稍微的有点呃懵是吧,诶涉及到string这块呢,我们涉及到字符,其实又关于这个字符集呢,诶需要做一个简单的说明啊,我就先简单的咱们先提一下啊,咱们在当初讲这个基本数据类型的时候,提到说一个差呢,是不是占两个字节。这个咱们指的是在这个内存层面。
12:02
在内存当中一个叉两个字节,也就是说我一个小A在内存里边呢,也得用两个字节来存。咱们实际上呢,咱们知道在X码当中。是大写的I是吧。在阿玛当中,这个小A呢,是不是就是97啊。哎,或者说我们这个实际呢,在存储的这个层面,就是硬盘这个层面呢,像abcd的话呢,其实一个。字节就存得下。就是在X码当中,其实它只用了幺一到这个128这个范围内的,其实就诶不是零到127这个范围内,其实就足可以够用了。啊,一个字节相当于他就能盛得下,然后呢,这个阿斯玛,然后比它呢,稍微的字数多一些呢,是一个拉丁的。这拉丁的话呢,他也没有超过一个字节,说白了就是哎,我们常见的这种abcd啊等等的,其实一个BA呢,就能存下这个,咱们说的是这种存储层面的。疯了。完了没有?没有啊,就是这块呢,你看有这么个事儿哈,比如说我这块呢,我新建一个T,我打开。
13:03
你看我写个ABC啊,我保存一下。这就存住了啊,那么现在的话呢,我们要点右键看这个属性,哎,属性呢,我们说看这个文件一般都会写有多少个字节是吧,那么你说我们这时候呢,有多少个字节。我写了个ABC。三个字节啊。呃,就是这个呢,咱们指的是这个存储层面啊,那么现在一双击呢,其实就把这个文件呢,加载到内存里了,那么在这个内存当中呢,呃,一个A是一个字符。一个B也是个字符,一个C也是个字符,这个内存当中这个叉呢,我们理解成了就是两一个字符啊,一个叉呢是两个字节。呃,现在这块呢,它为什么由这个差型数组改成BY的数组呢?呃,因为咱们知道这个,呃,美国人他们写代码的话呢,他们写的基本上都是这个英文的代码了。他们里边呢,去给这个string在复制的时候呢,那基本上也都是abcd嘛。加上欧洲的这些啊,那他们呢,其实用的都是。哎,这个。
14:01
这些都都算是拉丁体系的了啊呃,他们呢,其实用一个字节呢就能盛得下,那杨I呢,就是在内存中这个小A呢,他要是用两个字节去装的话呢,前面这块呢,始终都空一半呗。还有觉得挺浪费的。所以这块呢,他就给砍一半儿了。诶,所以呢,诶砍一半之后呢,这不就相当于变成叫bit数组了吗。就这个道理,但是对于我们汉字来讲的话呢,是不是就不太友好了?比如我们写一个中,这个中的话呢,在我们内存当中还就得是两个字节了。那怎么办呢?诶这块呢,它其实呢,就具体的细节就说了说呢,你如果呢,是基于这样的拉丁的话呢,那就是用一个字节去存一个字符,但是你要是呢,基于像咱们这个汉字这种场景呢,还是用两个字节拼在一起构成一个字符去作为一个字符。啊,也就是说呢,我们写汉字的话呢,那就相当于这个BAT俩现在还是个叉啊,但是你要是这个abcd的话呢,人家就是一个BAT了,节省一半的内存空间。哎,这呢,就是相当于从一个优化的角度呢,做了一个处理。
15:01
啊,肯定呢,还有同学,很多同学在懵,诶这个呢也是正常的,咱们后边呢,还会再去讲字符集的问题,子针这块会讲,后边呢,我们讲到这个转换流的时候呢,还会再说一下,诶转换流讲完之后呢,大家应该是就比较清楚了啊暂且呢,咱们先了解到这个程度啊,你知道为什么要改为了节省内存空间啊。为了节省。内存的这个空间啊,然后呢,做了优化。诶注意这块我们做的这个优化呢,不管这个string做优化了,跟string相关的类呢,都做了优化了,比如我们后边讲的这个string buffer呀,String builder啊,哎,他哥俩呢也给改了啊。这个大家做一个了解就行了啊,那下边这块呢,就提到说字符串常量的一个存储位置啊,这就涉及到什么问题呢,咱们这块呢,就开始来写相关的这种代码了。啊,String这块我们先叫一个。啊这呢来一个单元测试啊第一个啊,哎,那这块呢就提到了,比如我这呢,写一个叫hello。
16:05
哎,这样的写的啊,这个呢,我们把它呢称为呢叫字面量的定义方式。这个的话呢,它比较特别。也只有他呢,你看它是可以这样写的,按说呢,你是一个引用数据类型是一个类,那不应该new吗。是吧,哎,确实如此,但是呢,就死针比较特别,它呢可以直接通过这种字面量的方式呢进行了定义,而这种的定义方式呢,咱们说呀,这个哈呢,就放在了字符串常量池当中了。啊,就专门呢针对这个字符串呢,因为我们开发当中啊非常常用,所以呢,我们专门呢给它分配了一块空间,这个空间呢,就叫做字符串常量池。也就是说呢,我们这个字符串常量啊,都是存放在字符串常量池当中来存储的。好,我这块写一下啊。首先呢,第一个点。哎,字符串常量都存储在字符串常量池中。
17:04
这个塑料常量池呢,我们就可以呢,给它理解成了叫做,哎,有时候翻译过来就是string table是吧。那就它啊,那么这个字符串常量池呢,它有一个特点,就是这个池子当中啊,它是不允许存放两个相同的字符串常量的。啊,不允许存放。两个相同的。哎,字符串常量啊,那既然有这样的一个规定,那就意味着,诶,我要是再声明一个S2呢,也叫做哈。啊,注意这块呢,我们还是把这个所谓的这个实体对象的地址给了SSE了。这个也同样的道理啊,那既然呢,你是在常量池里的,然后呢,还不能存放相同的,只能意味着这俩是同一个是吧。那既然同一个给过来的,是不是就是同一个地址了?对,所以这块我们去打印的话呢,就会发现他俩的地址是一样的是吧。
18:02
你看这块我们打印的结果呢,就是一个处。哎,这呢,就是我们看到的这样的一个场景。啊,这样一个场景啊,好,这个呢,就是我们说的这个,呃,磁库扇常量池它的这样一个特点啊,这个特点的话呢,大家呢,一直需要呢去关注下一个问题,这个呢叫自符串常量池,它呢是内存中的一个部分,那我们下一个问题就要关注啊,这个为这个东西是吧?这个池子到底是放在哪儿呢?啊,这块呢,我们一句话呢,就说不完了,啊这个塑料常量池呢,我们说呢,在不同的这个JDK版本中。啊,这个存放位置啊不同。哎,那具体的是怎么来说呢?这块我写一下啊,在这个JDK。啊,怎么着呢,这题可七之前。我们这个自常量池存放在叫方法区。啊,然后呢,JDK7级之后。
19:00
哎,磁差常量池呢,存放在哎堆空间。诶,有这样的一个特征啊,然后这块的话呢,我也诶画了一下这个内存的结构的图,哎,稍微的我们看一眼啊,哎,针对于它。好,这块呢,我们看一下在JDK6当中的时候。哎,GK6当中的时候呢,这是呢,我们有两个东西啊,一个呢叫搜串常量池,一个呢叫静态域,静态域呢,就是我们前面讲的静态变量了啊,域呢就是嘛。然后这两个结构呢,都是存放在这个方法区的。这个呢,方法区的话呢,我们说呢,是Java虚拟规范当中的一个概念,在house这个虚拟当中呢,它其实呢,叫做永久带。啊叫pro space啊,就是用纽带的意思了,然后呢,在这个GD7的时候呢,诶,我们就把这个静态变量啊,也就是静态域和磁常量池都存放在了堆空间当中。啊,然后呢,这个呃气当中呢,这块呢,还叫永久贷。
20:00
然后呢,在G8当中的时候呢,还在这个对空间里。啊,只不过这时候呢,我们这个方法区呢,落地实现呢,不叫云带了啊,改成叫圆空间。啊,这个概念呢,大家不用过多去关注啊,如果这个不关注的话呢,其实你也只需要知道从七开始就放在了堆里边了。啊,那么你可能会问一下,为什么我们要把粗叉常量池从方法区改造微空间呢?这块呢,主要的一个原因还是出于这个GC的考虑。啊,这个JC呢,就是我们说的垃圾回收行为啊,然后这个JC的话呢,占空间呢,有JC吗。没有,原来说过了,他只有入账和出账是吧。啊,那么这个堆空间呢,是有的,号码区呢也有。但是呢,从实际呢,我们执行的效果上来看呢,这个堆呢,是我们比较频繁进行JC的一个场所,而这个方法区呢,很少进行GC,因为方法器里边主要呢,是加载了我们一些类的一些信息,这个类的话呢,轻易呢你回收也没有用。
21:03
回收也回收不掉。啊,因为这个类呢,它都会被相关的一些结构,包括一些类的加载器啊,都始终占用了,你试图去回收的时候呢,效果并不好,所以干脆呢,这个孵化区这块就很少回收了,但如果你要把这个租上常量池放在这个放化区的话呢,导致这个常量池的话呢,就越来越大,越来越大,而且还很很少被回收。所以呢,为了及时的我们去回收这一部分的内存空间,所以我们就把它移移到了这个堆空间里了。啊,就是这样的一个情况啊,哎,那么这块呢,为什么这个方法区呢,这块还改了个名呢,其实这块一个主要区别呢,就是从八开始呢,他开始使用我们本地的物理内存了。啊,因为呢,方法区域你不是回收效果也不好吗?那干脆的话呢,你就使用本地物理内存,呃,这个你就放开用得了。啊,那你要是这块挂了,那整个相当于我物理内存也也到头了是吧,所以这块你就放开用,我也不怎么管你了,主要呢,我关心的就是堆,所以呢,把我们比较关心的一些结构呢,就都往堆里边去放了。
22:01
哎,那这呢,就是搜查常量池和静态变量。OK啊,所以大家如果下来以后,你看到网上一些帖子,如果把这个搜R常量池呢,放到方法区呢,诶你也别理解成说他错了啊,只不过呢,他用的这个版本呢,是比较老的版本,可能你看这个图呢,就比较早而已啊OK。行,那么回过来啊,对应的我们这个知识点呢,就是在这儿。行,那么基本上呢,我们先针对这个string的话呢,有了一个简单的一个理解。好,那么下边的话呢,我们继续呢来说这个string,首先的话呢,这提到了它的一个特点,叫做string的不可变形。是不可变的特性啊,你别说不可变性啊,不是这个意思了啊,什么叫不可变的这种特性呢?来我们通过代码呢,来进行这个说明了。哎,这我写个二啊,这呢我们写一个说明啊,叫string的不可变形。好,那么这里边儿这不可变性呢,诶我就开始直接举例子了,比如说这块有个S1,比如说我们就叫做这个hello啊。
23:05
嗯,这个没问题,然后接着的话呢,我们来个S2,这个呢也叫hello。刚才我们刚说了,他俩呢,其实是同一个是吧。指向的是同一个这个数据了。接着的话呢,我们把这个S2吧,我改成叫氦了。啊,那么改完以后的话呢,我们看一下这个S1。啊,是hi呢,还是hello呢?啊,可能有同学说呢,嗯,本来没讲这个事的时候呢,还比较清楚是吧,讲完之后呢,就不敢说了。嗯,它指向了一个地址,它指向的地址,这个指向的地址变了。那不也跟着变了吗?没有是吧,没有就是咱们讲对象这块呢,其实也不影响你原来的是吧,相当于你又重新用了个新的一样是吧,所以这块呢,对于SSE来讲还是hello啊这块我们去run一下。
24:02
嗯,这个没问题是吧,这个哈,这个呢,如果我们要是画这个图的话,哎,我在后边这块也放了啊在这儿。啊,这个呢是咱们说的这个最基本的这个场景了,啊这个呢我们也先说一下,诶我呢S1S2都叫做hello,这呢对应是我们方法,诶现在这个战争呢,我们就进来了,这呢是一个。哎,这么着,然后呢,这儿呢,有一个S1。然后呢,S2啊,我就提前都写好了啊,然后呢哈呢,这个叫搜查常量池,这个我就没有明确的把它说放在堆还是放在方法区了,这个你看不同的版本了,总之呢,这叫常量池。这里边儿呢,我们有一个,哎,这个结构。换一个颜色啊。里边呢,放的是hello。哎,就他了。哎,当呢,你有S1的时候呢,这个呢,就把hello,这个时候,如果我们这个常量池里边没有这个哈呢,这时候就创建一个啊创建一个以后呢,它就会有一个地址值。然后我们给他这样一个地址值。
25:01
比如叫0S1122。诶把这个地址呢,就给了我们这个S1了啊011R,然后呢,我们S1呢,就指过去了。哎,就这样,然后当我们又声明一个叫哈,这是我们提到过成线池里边不能存放相同的字面量,所以呢,我们就还用的这个地址给了S2了。0S11R,所以呢,它呢也指向了。诶,我们常量池里边这个唯一的这样的一个,诶字面量了,所以呢,它俩的地址呢是一样的啊。好,那么在这样一个基础之上呢,我这儿呢,又声明一个叫S2 S2呢叫氦啊,可以理解成了在我们刚才这样的一个基础之上啊,CTRLC一下。诶把它呢先拿过来啊,拿过来以后的话呢,我们把S2呢做了一个修改。啊,那就相当于呢,我们此时呢,又创建了一个新的。啊,这时候呢,在这个搜叉长链池里边呢,没有这个氦,那我们就需要呢,先去声明一个。哎,交到这个害了。那这块呢,它也会有一个新的地址。
26:05
哎,0X比3344。哎,那我们就将这个34呢,给了我们这个S2了,哎,把S2的这个地址呢做一个修改。删一下啊。诶,0X3344。嗯,放在这儿。OK啊,那么进而的话呢,我们这个S2呢,就指向这样的一个新的地址了,原来的这个就不要了。原来的这个。哎,就把它删一下啊,这就可以了啊好,这呢就是我们目前的内存中的一个场景。啊,也就是说当啊可能理解为呢,说我们试图呢,对这个哈呢进行修改,呃,这时候呢,说不行,你得去新建一个,诶我们这个哈呢是不可变的。哎,这样个意思啊,回过来这块呢,我们可以在这儿呢做一个说明啊第一个。
27:03
呃,当。这个嗯,对。哎,字符串变量。重新赋值时。哎,这个时候呢,我们哎需要呢,重新呃指定啊一个哎字符串常量。啊,然后呢,呃,周砂长的这个位置是吧,来进行这个赋值不能在原有的位置。修改。那这个呢,就提到了我们这个叫不可变的一种场景啊好,这呢是一个了,然后接着我们再去写,我写一个三。啊。嗯,这块呢,我这样来处理啊,首先呢,这个叫S1。啊,然后这块呢,我们有一个S2。还是这样的场景,然后呢,接着我让这个S2呢,哎,S2是吧,加等于相当于一个内容,比如加等于一个叫word。
28:02
啊,那么此时的话呢,我们看这个S1。啊,是多少。Hello还是hello word呢?对这块呢,还是一个hello,哎,当然了,你要看这个S2的话呢,那你肯定是hello了是吧。对这个呢,他自己改了肯定是没问题的。来运行一下。嗯,你看这个是没问题的啊呃,也就是说呢,当我们呢,想在现有的这个字符串的基础上呢,拼接一个字符串的时候呢,这个呢,不好意思,你得重新的去再开辟一个空间了,你不能在原有的这个基础上呢去做这个修改。啊,我们把这呢写上。哎,当。啊,对,现有的。哎,字符串。啊进行叫拼接操作时。这个呢,我们需要,哎,重新开辟空间。
29:00
哎,然后呢,保存这个啊,拼接以后的字串。诶,不能在原有位置修改。这个呢,也体现为呢,就是原有的我们这个位置呢,是不可变的。啊,对应的我们这个图的话呢,咱们也可以呢画一下啊,哎,这块呢,我们拼接的是一个艾特硅谷了。嗯,这块对应的啊,你看这个图呢,明显呢,这个结构呢,似乎要复杂一些了啊。好,他进来以后。哎,这么着啊,然后呢,在这个位置呢,我们写一个没方法。现在是一个S1。哎,指向我们这个hello啊这呢,我就还是借用一下这个内容啊,哎,包括这个地址值,OK ctrl c一下。啊,回过来啊,粘过来。这个我就放到这儿了。嗯,这样啊好,那么把这个地址呢,就给了我们这个一啊0S1122。IC呢,就过来了。哎,这是他没问题,然后接着的话呢,我们就有一个叫S2,这S2的话呢,哎,这不也叫hello吗?这个地址呢,跟他一样啊1122。
30:06
哎,也指向了他。诶这个这样的它好,然后下边的话呢,我们这S2呢,又拼接了一个叫爱硅谷,那不能在原有的这个位置去改了,得新造一个是吧,这个新造的话呢,其实可能跟我们想的这个位置啊就不太一样了。啊什么意思啊,就我们可能可能会认为说你新拼接这个,那不就在我们现有的这个位置上。哎,现有的这个位置上,哎,我们这样复制一份放在这儿了吗。呃,其实呢,你注意这种操作的话呢,它其实拿现有的变量呢,去拼接一个字符串,咱们接下来的话呢,其实也会讲这个事儿哈,它不是放在这儿的。对,它其实呢,就给放到堆里边了。啊,然后对应的这个对象呢,叫一个说白了就是这是new的一个对象啊。啊,就是这个呢,一说呢,稍微有点多了,大家你可能只需要知道呢,就是现在我们想演示这个叫不可变性。
31:03
哎,从这个角度来讲呢,首先不是在这儿改的,哎知道这个就行啊,这个事儿的话呢,咱们一会儿呢回去讲。所以呢,这时候呢,我们就会有这个新的这个。哎,这个地址值是吧,哎这呢,我就复制一份了啊。哎,比如说这个呢,我们叫哎3344。哎,从这个准确准确度的角度来讲呢,我其实应该放在这儿,只不过大家呢,现在猛一下还有点儿不太熟悉啊。把这个呢,给它改掉。诶,我们叫这个,诶0X3344。哎,放到这儿啊。行,这是原来这个地址了,诶。再往后一点啊。那新的这个地址呢,有了以后呢,我们就让它呢,就指向了是这个结构了。好,那原来的这个地址呢,我们就不要了。哎,这个注意一下。
32:01
那么这时候呢,显然我们这个S1呢,还是人家的hello,然后S2已经变成了叫hello。这个呢,我们也理解成了叫不可变的这种特性啊。啊,你不能在原来的位置呢去修改。好,这是一个啊,然后再接着。啊,我再写个四啊,这个呢是这样的,这个呢,我来一个一啊,这个我们叫hello。啊,这没问题啊,然后string的一个SR。还是那叫哈。可以了啊好,然后呢,这个S2呢,我们后边会讲个方法叫做replace啊。Replace呢,叫做替换的意思了。这个替换的话呢,我们这儿呢,就考虑比如说把这个L呢,我就替换成这个叫W了。诶,就这样的一个行为是吧,那么这个替换以后呢,来我们看一下这个事儿啊,首先呢,这个方法调用完以后呢,它返回的还是一个钝。那我就在这儿呢,可以去做一个接收。啊,这个叫S3,那现在我们关心的点呢,就是这哥仨呢,到底都分别是多少。
33:08
第一个。诶,第一个呢,我们知道不可变性的话呢,它还是含露是吧,S2呢。Hello,啊,这个底气呢,稍微有点不足了是吧?哎,其实是哈,那这个呢。这个就。哇,这个就这个也能念啊哈。啊。来run一下。你看就是这样的是吧。诶,这样个场景啊,那么这个replace呢,底层它到底是做的什么样的操作呢?哎,这个你可以看一看,诶实际上的话呢,它也是新new了一个对象啊。啊,就是一个新的一个对象了。行,那这个呢,咱们要是画一下内存图是什么样的呢。啊,就是我们下边这个了。哎,我这呢,做了一个replace这样一个行为,OK。嗯,咱们呢,先基于咱们上面这个图啊。相当于我得借用一下这块了。
34:01
哎,先这么着啊,CTRLC。哎,我这块粘了一下,这个呢,暂时呢还没有,它这个还没有。哎先目前呢是这么着的,这块呢都是hello,实际上是他,然后现在呢,这个S2呢,做了一个replace,把L呢改成W了,刚才呢,我们稍微的看了一下底层的一个源码是吧。源码的话呢,其实它本质上来讲,这不还是掉了一个new吗。啊,所以说呢,就新创建了,那这个的话呢,咱们说过了,是不是就得是在堆里了。诶,所以这块呢,我们得在这呢去新给他整一份了,这个呢叫hew o了。行,然后呢,它这块呢,也会有一个这个对应的这个地址值。哎,放在我们的这个位置啊,这个呢,我们比如说改成。诶这个叫S3344好,然后呢,这个S2的话呢,诶这个呢,体现呢叫什么呀,叫不可变形,怎么着呢,就是我这个S2的话呢,还是这个哈,是这个返回值是一个新的这个变量,也就你这个方法呢,调用完以后,你不是刚才呢,看这个源码的时候呢,它是一个。
35:06
诶这块呢,Return的一个当前你这个new的对象嘛,诶return的这个结构呢,给了我们这个S3了。诶给了这个S3了,所以这块呢,你是得再往下是吧,来一个S3它的这个地址。诶是0X3344啊,这个我们这个站。稍微往下一点啊。好,然后呢,我们这个指针的话呢,这就从他这儿来指项链了。然后本身S2呢,还是这个hello。诶这块呢,其实我们想强调点呢,就是你不能在这个位置去把这两个L呢改成W。比如S1跟S2呢,注意不是。嗯,这个hew wo啊,他俩还是lo。啊,回过来相当于我们的啊这块。在这儿呢,再说明一下。这是我们的第三个点。啊,那就是当调用字符串的叫replace方法时。
36:03
啊,方法叫替换。现有的。诶,某个字符时。啊,这个时候我们说呢,仍然啊需要呢,重新开辟空间保存,这个你是修改以后的这个组串。字符串,然后呢,不能在原有的位置呢去修改。啊,那么这儿呢,都提到了这样一个事儿,我们把这个事儿呢,就理解为叫钝的不可变形。啊,这个大家呢,去体会一下,这呢三个。好,CTRLC一下粘过来,对应的就是我们这样的一个问题。哎,OK啊行,这个呢,大家理解理解。来把这个我们填一下。
我来说两句