00:00
那行了,同学们,那接下来呢,我们就把昨天给大家布置的这两个作业呢,我们一起来画一画图好吧,我再我带着大家来画好吧。来我先打开谁呢?我先打开我这个D盘cost加product,然后零二,然后呢,CHAPTER0909这块的话,我们找找一个user和user test啊,那么首先呢,User和user test user这个打开啊,然后呢,紧接着呢是user test是不是啊user test。嗯。来我们看看user是一个普通的类public class user是不是in此类型的ID啊,Spring类型user啊,啊,String类型的什么呀,字符串password是不是,哎,然后紧接着在这块是什么呀?哎,User是不是,哎,New user对吧?哎,那么这块的话,我们这样啊,我们先不去运行它,也不去编译它,我们先把内存图画出来,然后我们猜测它的输出结果好不好,我们猜测它的输出结果啊。嗯,那行了各位,那这块这个图怎么画呢?来,我们还是把这个画板打开。这个画板打开呢。这样啊,我还是。
01:01
给它缩小一下啊。来我保存一下先啊,先把这个图保存到这个document的目录下来啊,然后这块呢,咱们这个写上,呃,叫做什么user test程序执行内存图啊,来这个画图啊,首先呢,我要本着刚才我所说的那几点,各位啊,大家不要随便来啊,不要随便来。就这个程序是有执行顺序的,好吧。另外内存上不要体现代码啊,一定要达到这种效果啊,来这个线条咱们调一下。来这样画一下啊,这个呢,假设就是你脑袋里边想象的这个j vm Java虚拟机是不是,哎,然后Java虚拟机这块,首先我们三块内存空间是能画的啊这个没办法是不是,哎,一个是什么呢?方法区一个是什么呀?哎,就是我们所说的堆啊,还有一一个什么呀啊一个是我们的一个啊叫做占啊一个是占。那么这块呢,咱们该写还是要写上啊,这是什么方法区啊对不对,哎,方法区啊是不是,哎,然后呢,堆内存啊或者堆区啊,哎,堆内存然后这块的话,我们画上一个叫什么呀,叫做占的一个东西啊,那这块呢,我们就把这个头给它去了啊,头给它去了删掉来,我们这个呢叫做占。
02:15
啊叫sta啊sta好了,那么这块呢,咱们把这几个准备好之后,下来什么呢?我们程序说要走我们一我们走一步,我们看一步啊首先第一步是什么,是不是类装载。是不是加载呀。就是我们程序执行第一步是不是先进行类的加载。就你现在相当于在这块呢,你假如说CMD敲进去,然后呢,Java c呢,干什么编译我们的user test.java是不是,哎编译之后呢,大家知道,诶你看还找不到符号。第六行找不到符号,这是什么原因?呃,User test编译的时候呢,这个user user Java生成。看一下这样C我们先编一下,又是里va编译一下。
03:03
没问题,Java c编译一下user test叫Java。找不到符号第六行找不到符号。嗯。第六行。U1。有the name。哦,写错了各位啊,写错了这是user是吧?在这改改username啊,我改成username,这这写成user了是吧,Username啊,Username写错,你看写错了它就有问题是吧,还就有问题啊username password来再来看看。再来看一下啊,昨天应该大家应该发现这个问题了吧,啊,发现这个问题了啊,来Java c user test.java啊好,来家看现在是没有这个问题的啊,我们Java去运行u test就从这我们写上就是敲回车,我们一旦敲完回车之后,这个程序发生了什么呢?它实际上会去这个类加载器会硬盘上找这个u test文件。
04:04
他会去找谁啊,找这个类,找这个类之后,他会把这个类装载进来,但是你这个类是不是依赖这个类。因为你的代码里边是不是有这个string这个类,因为你的代码里边是不是user有user这个类啊,对吧?哎,严格意义上讲还有这个system这个类,我不知道大家有没有,有没有画上去啊,有没有画上去这个system.out.print哎,你是否还记得这个实际上system它也是一个类,对吧?它是不是也是一个类啊。哎,这个我就不再翻了,各位啊,那这块实际上呢,我们要就要说进行完全的一个类类装载的话,它应该是它装载进来,它应该装载进来,它应该装载进来,它是不是也应该装载进来,那么也就是说第一步你要画的是在我们方法区里边,实际上是由我们这样的代码的什么代码呀来。有这些代码,比如说叫有点什么呀,test.class是不是有有点class有点什么class有system点什么?哎,system.class。同学们啊,就别着急啊,画图的时候不要着急,不要着急,就是这个东西,它是一个代码片段,就是代码片段。
05:06
另外大家图的时候切杜老师那个么。好,那么接下来我问大家,如果说你在程序里边把这个类已经加载了,类加载完成之后呢,接下来你是不是要执行你的程序,执行你程序,来咱们说吧,同学们。第一步。类加载,那你第二步该干嘛了呢?假如说你这个类已经加载进去了,就这个类加载完之后,是不是要调你这个类的main方法入口,是不是第二步就是调用什么呀?调用main方法,那调用谁的main方法调用实际上是user test这个类的,哎,这本方法是不是那么那么大家脑袋里边现在应该有一个什么意识,你们知道吗?就是说方法调用要压战啊。我觉得如果说你要是有这个意识的话,压。
06:02
压榨。方法调用要压站啊,如果你有这个意识的话,我觉得这个程序再往下画的时候你就会画。那你说方法方法执行,你方法只要执行就会压站,所以这个时候呢,我们在站里边是不是有一有一块空间就压进来了,对吧。啊,有一块空间,那么这块空间咱们用一下这个蓝色吧,假如说蓝色来,那这个线条的话,我们就用这个线条吧,来我们这块呢,给它压进来啊,假如说这就是那个所谓的什么呀,叫做问方法。对吧,整个在当中底部其实就是方法给它分配出来了啊,这就是方法。战争,那你焖方法,战针压进来之后,那你焖方法就开始执行喽。那你问方法开始执行,怎么执行,那就一行一行一行一行一行一行一行执行呗,对吧?哎,一行一行执行,我们先不要先急着看第八行,我们应该先看第七行,各位。那第七行这一块我们应该怎么看?第七行里边它是不是也有先后顺序,就万变不离其宗,各位我不知道大家理解不理解,就是画图的时候一定是一定是一定是程序执行到哪画哪啊,你千万别越界啊,别越界,你比如说先执行这一行,那么这一行里面是不是也有先后顺序,那么先后顺序是什么呢?是等号的右边先执行啊。
07:18
对吧,等号右边先执行,执行完之后呢,把等号执行右边执行的这个对象对吧?创建的这个对象,对象就创建完了,创建完之后呢,怎么办呢?哎,付给了我们这个U1,那这个U1呢,它没有在这儿,它代码并没有这样写,各位代码并没有这样写啊,并没有这样写,大家都知道,如果写在这里,这叫什么成员变量对吗。你管他那么多呢,对不对?哎,大家想这是不是成员变量,并且我们昨天说了这叫实例变量,对吗。是不是我们并没有往这个位置写对吧?哎,我们这个U是不是写在这个位置上啊,是不是写在这个位置上啊。对吧,我们写在了方法里边一个变量,还记不记得方法体当中声明的变量,就方法体里边生变叫什么?方法体当中声明的变量叫做局部变量,对吗?方法体外声明的变量,方法体外这叫方法体外声明的变量叫做哎成员变量,我不知道大家诶有没有去记这个概念啊,光学光学天天学是吧?我之前我有没有给大家说这个事,大家先背会是吧?诶当时你到底背会了吗?诶那如果说你现在背会了,知道这个事儿,那你知道这个变量啊,它是一个局部变量,那你既然知道局部变量,那你就一定是知道它这个变量,哎是在哪一个地方存储,对吧?因为我昨天我说了很多很多遍,但凡是局部,局部变量都是往哪存啊,哎都是往我们占的,哎,里边存储局部变量,那么但现在局部变量内存空间还没有开出来,是等号的,右边先执行各位,所以。
08:55
那你就先墨迹一下啊,墨迹一下你先不要去画左边,明白吗?你应该画等号的右边,右边是对象,那既然是拗对象的话,大家想哎,你一个对象出来。
09:05
好了,各位看好了,那这个对象new的时候,这个变量是不是它的默认值是零,这个默认值是none,这个默认值是不是啊?对吧?哎,一个对象有了,它对象里边是不是应该放成员变量,放实例变量啊,所以这也是变量,各位因特类型ID好,回来这儿看,这个呢也是变量,那它们的区别在什么地方,如果你在方法体里边叫局部,对吧?你看你这个user这个类,你就很明显的看到这个变量它是在什么呀,类体当中的,而在类体当中这个变量就属于什么呀?哎,就属于成员变量对不对?成员变量啊,属于实例变量啊,实例变量属于对象变量是不是?哎,属于对象变量,一个对象,一个对象一份,一个对象一份,你100个用户的ID有100个ID 100个用户有100个ID 100个用户有100ID,十个用户有十个IDID都不一样,所以说你这个ID肯定是我们对象级别的。另外昨天我也解释了,用访问这个访问访问什么呀,访问ID不能这样,不能这样不能怎样说U点点ID不能不能,这是错误的啊,这是错误的,错误的实例变量,实例变量不能用类名访问啊,不能用类名,你不能说你用一个类名去访问这个ID是不允许的,那这个ID的访问,这个ID的访问必须先造对象,先造对象啊,然后对象有了才能访问对象的ID啊,实际上是这样的。
10:30
啊,我不知道这么说大家理解不解,这个这个这个东西你要千万要记住啊,不能说只接类名吧,访问一下你不可能啊,你不合逻辑啊,你这个不用死记硬背啊,为什么?因为ID这个东西是一个用户的ID跟一个用户的ID是不一样的,你既然是不一样的,那肯定这个ID是一个什么呀,是一个对象级别的一个一个一个一个变量,所以说你得先把对象造出来,对象有了之后,你才能通过对象去访问我们这个就这个这个数据,实际上说白了没有对象就没有他。没有对象就没有他,你想想一个人一个人对吧,哎,我们有有有一个叫人类是不是,哎,那么人类是不是有一个叫做身高啊,各位是不是叫身高啊是吧?哎,身高那我问你没有没有实际存在的人哪有身高啊。
11:12
对吧,你是不是得先把一个人造出来,这个人才有身高这一说呀,是不是我们是不是必须得把先把人造出来,是不是才能访问身高,所以这块的话,哎,你要去尽可能的去理解这种东西啊,像这个它也属于什么呀,叫做成员变量啊啊实例变量啊啊对象级别变量啊哎先造对象对不对,哎先造对象才能访问啊才能访,那像这种变量存在哪,你要知道啊,你要知道它变量存在哪,这些这些这些变量存在什么空间上,你可千万别把这个这个变量它空间放到这个地方,那那就不对了,就不对了啊行,那咱们程序继续往下啊等号右边先执行,就会把user对象创建出来,所以这个时候啊,我们把U的对象啊就造出来了,假如说这个就是那U的对象。画个方框了,方框也行,圆形无所谓啊,无所谓,这个呢,其实就是那个user对象啊,叫user对象,叫user类型的对象啊,User类型的对象啊,User类型的对象。
12:13
各位啊,U的类型的对象好了,那么这个U的类型对象啊,它通过我们new的方式创建出来之后,这个对象它刚刚创建完,它就是有这个这个这个这个这个就是有ID的,就是有u name,就是有password,那我昨天我也说了,就是说什么呀,就是成员变量可以不手动赋值,系统赋什么呀,默认值系统附默认值啊,就是昨天所说的,哎,这个BA short in long float double bulling char是不是,哎它的默认值是啥?是不是,哎默认值是什么?如果你是,哎这个引用类型对吧,哎默认值是什么这个。这些默认值偏向什么呀?哎,偏向零,False也是零对吧?啊,即使这个布尔类型它是false false是吧,它是不是也是零啊,啊其实也是零啊,引用类型它的就是none啊对不对,所以说这个是零,这个是none,这是none啊所以这个时候呢,你要注意在这个地方啊,它实际上有有有有有就逻辑上啊有三管空间。
13:17
对吧?哎一块空间是什么呢?哎存什么呀,存一个零,你看我说的只画数据各位啊存一个零,然后呢,他这里可能还有一块空间干啥呀?哎去存什么呀,可能没那么规则,各位啊,没那么规则,不像这样,哎那么规则来存什么呀?哎那是不是,哎还有一个空间是什么呀?诶是存什么呀?哎是存这个叫做。那是不是,哎,那只不过就是说你现在啊,这个变量啊,它的类型是什么呀,是一个int类型。对吧,是个int类型,并且呢,它是一个什么呀?哎,叫什么呀,叫做ID对不对,哎,Int类型ID啊,Int类型ID说的是它。是不是,哎,那么我们在这个位置上,那只不过它的类型是string呗,对吧,哎叫username呗,对不对,哎,Username说的是谁啊,哎说的是他。
14:05
对吧,哎,然后接下来这个无非可能就是说,哎,我们string类型是不是哎password对吧?哎,那么这个password呢,说的哎就是我们这个。这块内存空间啊,就是说你的你的内存图上应该体现的是什么呢?是数据各位啊,其实这些东西都是我后期画的,这东西是不存在的啊,是跟这个没关系的,其实你的内存当中只有这么几个数据。啊,其实哎,我这是为了帮助大家理解才这么画的,各位啊好了,那现在验证一下你这个程序到底对不对?好各位,我们现在下边代码先不看,我们在这个位置点out.printline打印,我输出UE点什么ID行吧,system.out.printline打印我们输出什么呀?哎,我们输出这个UE点什么呀?U一点这个叫做username是不是?诶然后system.out点打印我们输出什么呀?哎,我们输出这个叫UE点什么呀?哎,Password,那么大家一定要注意啊,我们昨天说了一个非常啊昨天啊很重的一个内容啊,这个内容是什么?就是说成员变量,实例变量怎么访,实例变量怎么访问,怎么访问啊,就是属性怎么访问,属性属性怎么访问的事儿,各位怎么访问呀?哎,就是语法是什么,是引用点是不是,哎是不是引用点对吧,后面跟什么跟属性名呗。
15:22
是不是跟属性名啊,对吧,那这个U1是啥呀?U1是不是就是引用啊,对不对,是个引用啊,是不是啊,那你这一块的代码执行结束之后,你这个对象有了,有了之后你通过等号的方式给了谁啊,给了UU是个局部变量,各位大家一听局部变量就知道了,局部变量是在哪啊,是在这里啊。是在这里啊。对吧,方法里局变啊对吧,这个其实就是那个user对么呀,是不是这个里边存的是什么东西呢?哎,可能是这个对象的内存地址,这个对象可能是0X1234。
16:00
对吧,哎,存了个地址,存了个地址,而这个地址实际上指向了谁呢?哎,指向了我们这个对象。指向我们这个对象啊,程序员没有权利在我们Java中没有权利直接操作我们堆内存,这个是我昨天已经说过了啊,说过了啊,就是程序员要想要想访问你这块内存空间,你必须通过你的这个引用去访问。啊,可以通过引用去访问。必须通过U1去访问啊,这个U1是谁就是他。UE就是它。啊,这就是那个那个那个变量,那个变量。注意啊,这个内存地址,这个内存地址。这个内存地址是U1的内存地址还是这个对象的内存地址,各位。U1是一个变量,各位啊,这个变量占不占空间?在吗?对吧,哎,这块空间有没有地址啊,有吧,它这个变量里边保存的这个值,同时也是一个什么内存地址,你要想学细致的话,其实可以考虑的细一些。
17:04
你就像你在你的程序里边写了一个什么呀?Int类型I等于100,我问大家问题,I里边存的是啥呀?I里边的是不是100啊。那I本身有没有内存地址啊各位。I本身有没有内存?来给个回复,I本身有没有内存地址啊?就是在你程序里边,假如说你有一个你,哎在这儿有一个什么呀,Int类型的什么I等于100。对吧,哎,I等于100,那么接下来是不是就相当于在这个位置上有一个什么各位。好好想想啊,在这儿是不是应该有一个100呀?对吧,哎,并且它是什么呀?哎,In特I吧,对不对,哎,这个I变量是不是就是它呀。对吧,那你这个I,哎,就是你什么意思啊,我我的意思是就这个方框。它是不是在方法里面也占空间,所以这个方框有没有内存地址有。
18:00
这个I变量里边保存的这个值是个啥?是个100的数字对不对。这就是区别对吧,而你上面这个U的U1呢,这个U1其实大家想一想,这个U1就是这个方框是不是,哎,这个方框占不占空间,占吧,只要占空间是不是本身它就是有内存地址的对吧?那只不过这个变量里边保存的这个值不是100,你不像这里它保存的是100数字,而我这个变量里边保存的是0X1234,而0X1234是这个对象的地址啊。这个对应的地址。听明白了吗?听明白的话打个一来,各位打个一来,听明白的话打个一来。有没有听懂这这块这块的东西就是追,如果追踪的细致的话,你你往下追踪的特别细致的话,就是这样的各位啊,就是这样的。啊,就是说这里我我可以提醒一下啊,可以提醒一下,就是0X1234啊,我在这儿呢,这样我把这个时间删了。先删掉啊。删掉啊U1和内存地址和保存的地址不一样是吧。那肯定不一样,那咋能一样呢?那一样那就完蛋了,0X1234是你这个对象在堆内存,那个内存地址你UE的内存地,你UE的内存地址是在这块空间上的地址肯定不一样了,就像你家在南京,我家在江苏一样,是不是,那咋能一样啊,是不是不一样啊,区域都不同,这个0X1234是这个对象内存地址,你UE本身是一个内存空间,你内存空间上也有地址啊。
19:22
是肯定是有地址的啊,肯定是这个东西很好理解的啊,U1是一个什么呀,局部是一个慢方法,局部变量。本身啊是有内存地址的啊,但不是什么呀,0X1234。啊,但不是0X1234 0x1234是谁的地址?0X1234是这个对象的地址,明白吧,0X1234啊是这个对象,是这个堆内存对象的内存地址,明白吗?你要知道这个事儿啊,就是说0X1234是什么呢?哎,是这个堆内存,堆内存这个对象的一个地址,就是这个对象的地址,明白吗?这个对象的地址是零一,0X1234,只不过这个对象的0X1234这个地址放到了这个这个UU的U这个局部变量里边了。
20:15
但是你又是个变量,你变量就有就有空间,你空间就有地址啊,其实你这个盒,你也就是说大家思考一个问题,这个盒子有地址,这个盒子有地址吗。这个盒子是不是也有地址啊?你这个盒子难道没有地址吗?对吧,嗯。不是先执行new吗?箭头不应该是对象,呃,箭头指向问不是不是啊,兰芳这个理解错了,理解错了啊,这个指针是说地址跟先后,跟代码先后顺序没关系啊,跟代码先后顺序没关系,记住了,只能是说地址指向对象,没有说对象指向地址这一说。没有这一说啊,就相当于你手里拿了一个,你你要放风筝,这个就是风筝,你手里拿的这是这条,这是条线。
21:03
对,这个地址一定是指向这个对象的,不能电箭头反过来啊,不能箭头反过来。不能,你说的那是兰芳说的那是负值,明白吧,负值啊,蓝芳说的是那个负值,就是负,这个箭头体现的是个负值,记住了啊,实际上这个箭头就是指针。加箭头指。C加加中箭头实际上就是指针。只有地址,只有地址注意啊,说这个箭头呢啊,只有地址指向对象,没有对象指向地址这一说。啊,这个箭头必须得这样画。必须得这样画啊,好。嗯,Int I等于100,这个100也保存在站内吗?那肯定的呀,那那地值那。I的地址指向占内存本身吗?I的地址指向占内存本身I的地址。
22:03
I的地址,I的地址I的地址。啥意思啊?I的地址就是I的地址啊,不指向哪啊。你比如说U1它有地址啊,它就是有地址啊,那你这个U1这个这个地址,你你可能比如说这个U1的,U1的地址是0X,就是0X2345 0x2345呢,说的是谁呢?哎,说的可能就是这个这个比如说这个这个方框的地址。这是UE的地址,UE的地址。对吧,诶UU谁啊,U1的地址。啊。啊优的地址就是,但是我觉得这个可以忽略,各位现在先不要搞这么复杂。现在你只要知道0X1234是这个对象的内存地址就行了。
23:05
啊。这个对象的内存地址就是它。0X123就是这个对象内存地址。啊,实际我我在这里啊,我我注意一下吧,U1实际上是一个变量。这个变量实际上也是有地址的啊,这个变量实际上也是有地址的。因特I等于100对吧,I变量,I变量也是占有空间的,I变量实际上也是有什么呀地址的。不过I里边存的是100。这个数字啊,不过I里面存储的是数字100。啊,数字100。好,咱们先不说这个目录了啊,不说目录了,那么这一块呢,我们程序员是可以直接操作,我们直接操作占内存的,各位这是没问题的,我们访问站里边这个变量是没有任何问题的。
24:10
啊,那访问这个上面的数据只能通过UE的方式去访问啊,UE方式去访问,所以这个时候我们这个程序啊,应该是怎么做呀,哎,到这你应该知道我们应该是U1.id是啥,你U1是谁呀。就是这个呀。对。访问就是他了啊,所以说大家看在这个访问的过程当中,我们这个内存图只要画出来,我们都很清晰的知道这个是零对吧?哎,这个是啥呀?这个是none对不对?哎,这个是none,然后接下来这个是什么呢?哎,这个是。所以我们来看一看Java c呢,去编译一下Java,去运行user test走user test走好大家看上面是不是零零铛铛对不对,哎,零的结果为什么就是这样的,对吧?跟这个内存图是有关系的。
25:00
啊,你不执行这个代码,它也是零铛铛,你明白吗?就这个代码不执行你下边这三行代码,你不输出ID,不输出u nameme,不输出password,不输出这代码都没有,哎,你的ID,还有你的u nameme,还有你的password都是什么,都是零铛铛啊没问题的,没问题的,跟这三行代码没关系,各位啊,就是说你这一行代码执行到第13行,你这一行代码它所对的内内存图就是这样一个内存。就是这样一个内存图,各位。就是这样,内存图好了,这个第一步的一个,诶分析,我们就分析到这儿,好吧,就分析到这儿。
我来说两句