00:01
好了各位,那么咱们就继续再往下吧,再往下啊,再往下的话,我们得看一看这个昨天说的这个比较难度比较大的这个这个程序了。是吧,哎,难度较大的,这个我们看看内存,内存图是怎样的,好吧,哎,然后接下来我们先编一下看看有没有问题,语法上啊CD。Java c形成Java编译。我。先把这个关了啊,把这个地方也关掉啊,都关掉,这是笔记咱就不能关了啊,然后呢。嗯。把这个user打开啊,然后呢,把这个address打开啊,然后呢,再把这个叫test打开啊,一共三个程序,好一会儿看一下啊,首先呢,第一个呢是实际上第一个应该是这个address啊,这个address这个类,这个类呢,里边有三个什么,这是个什么变量啊各位。
01:02
什么变量在这叫什么变量,叫我又说了叫什么变量,叫实例变量是不是,哎实例变量啊。然后呢?这个呢?里边这个这个这个是不是也是个实例变量,实例变量,实例变量吧,是不是实例变量啊。哎,先承认一下各位。这个理解。这个就想象成int I呗。一样吧。印的是什么呀?基本数据类型对吗?是不是?什么?引用数据类型呗。I是什么呀?变量名呗,那这个a drr是啥呀?是不是也是个变量名啊?是不是一个变量名啊。对吧,哎,变量名。Int是数据类型吗?基本的这是什么?
02:01
变量名啊啊,这个是个什么。引用数据类型,这是啥呀?啥呀?变量名呗,这是什么类型啊?引用数据类型这是什么呀?变量名呗,是不是?哎,变量名啊,行了,只不过这个程序的特点是我们以前从来没有说在我们的class里边写上自定义的这个类。对吧,这个类是你自定义的,这是个变量,这是个变量啊,这是属性,各位还记不记得一个类等于属性加方法,类等于什么属性加方法对吗?是不是属性加方法?好,现在这三个是不是都是属性?以下三个都是属性吧?以下三个都是什么呀?属性都是实例变量对不对?哎,都是实例变量。都是实例变量啊,实例变量叫什么变量啊,叫对象变量吗?是不是叫对象变量啊,哎,是不是先把对象造出来,是不是它它它的内存空间才会开出来啊,你不造这个对象,这个这个这个内存空间是不是不会开啊,是不是?哎,那把类熟悉一下啊,User里面是ID user name address,那这个address里边是啥呢?这是一个类是吧?有有zip code,好,那么再往下呢,有个test程序,测试程序,那这个测试程序呢,我们从这个位开始。
03:18
啊,或者是从这个类加载开始吧,来,那么接下来把这个图画一下啊。那么这个图呢,首先第一个呢,我们还是要在这儿呢,先画一个什么呢。假如说这个是JVM。这边M啊好了,那么接下来呢,这里边该画的还得画一下,比如说这个是什么呀?方法区呗,这是什么呀?哎,比如这就是我们所说的堆内存啊,这是什么呀,假如就是占啊,就占来这块呢,该删呢,咱们删一下啊删一下啊来写一下这个呢是我们的一个叫做方法区啊,然后呢,这个是堆内存啊,然后这个是占。
04:03
啊,站stack stack。好了,那么接下来呢,我们在首先第一个就是我们要进行什么呀,类加载类加载啊来我们先把这个图保存一下啊,别一会儿丢了,那保存到哪呢?Document下边我们直接呢在这写上去,这叫什么叫做难度较大的内存啊难度。叫做难度较大内存图啊,就这么标一下吧,大家能看懂就行啊,那么接下来呢,这个首先第一个是进行类加载,这个类,这个类,还有这个address类,这个user类,这个类,对吧,都会装载到我们的一个。哎,装载到我们的一个这个方法区当中,所以这是会先进行类加载,那进行类加载这块呢,咱们就简单的来画一下啊,这是谁啊,就是一个test加class是不是,哎然后呢,点class,然后system.class还有谁啊叫user.class是不是address什么,哎,点class啊等等等等啊在这放代码片段,把它装载进来,那么接下来首先第一步呢,先执行这个闷方法,我说了闷方法执行就一定要走一步看一步,这就是那个焖方法。
05:12
可以这样去理解,这就是根本方法。这就是那个焖方法,各位啊,焖方法占真是吧,压进来之后,接下来就开始执行第一行代码,第一行代码等号的右边先执行。等号的右边先直行,右边直行就把这个对象造出来了,那么对象造出来造的是哪个对象?Address对象address对象往哪走啊,往这走。好,大家看这个对象造出来这个值是不是钠,这个值是不是none,这个值是不是none对吧?好,那这个我觉得在内存图上,我觉得大家应该问题不大啊,问题不大来,这是一个什么对象啊,哎,这个叫做address对象啊,叫做a address address类型的对象啊,这个类型的对象,那么这个类型的对象呢,接下来呢,我们给它,嗯写上什么呢?这个对象啊,New的new了之后呢,我们这个对象它这块呢,这个实例变量,实例变量,实例变量它都是引用类型,引用类型,引用类型对吧?那那city street和IP code,那么也就是说。
06:11
我们在内存图上是展现出什么的呢?来卡住了啊老卡来这块的话,咱们就写上啊,这个叫做什么呀?Nu是不是,哎这个呢,还有一个什么呀,叫nu啊,还有一个囊啊还有一个囊是不是,哎,None代表什么呀?空啊空来那么这块呢,我们给它框上去啊来这是一个。对吧,哎,这是一个是不是,哎,这是一个对不对啊,哎,那么接下来这个是什么呀?啊,其实这个就是啊CT呗。是不是,哎,然后这个呢,是什么呀,Street呗,街道呗,是不是,哎,那这个是什么呀?啊,这个可能就是说zip code。是不是,哎,邮编邮编啊邮编就这个意思啊,No nono啊都他们都是什么类型啊,润润润啊,都是润啊润。
07:06
啊,字符串字符串啊,来这边也是字符串啊,这个也是什么呀,字符串啊字符串。字符串啊好了,那么这块呢,咱们把这个内存图画出来之后,这个对象创建完了,这个对象创建完之后呢,接下来这个对象的内存地址,这个对象在哪的内存地址啊,在这个堆里边的这个内存地址是不是,哎,然后这个内存地址通过等号的方式付给了A,而呢,在main方法当中,它是一个什么变量,是局部变量对吧?是局部变量,那这个时候是不是应该在我们的这个叫做占内存当中。会有一个什么呀,哎,叫做。Address a是不是哎address a,而address a呢,它是个变量啊。对不对,哎,它是个变量,是个变量。啊,这个A是一个是一个局部变量,明白吗。
08:01
这就是那个A里边保存了一个什么呀,内存地址,这个内存假如说0X1478啊0X1478,而这个0X1478呢,实际上哎,这个地址是这个是这个是这个这块的这个啊address对象的这个这个这个这个对象的一个地址啊对应的地址,那么也就是说记住啊,A里边保存的什么呀,是一个012018的这样的一个内存地址啊,内存地址内存。好了,那么这块呢,咱们就呃,就说到这儿啊,这是到哪呢,各位这到这个位置上。是不是好,接下来他又开始做了,说a. Ca. streeta.c code,那这个A是谁?指的就是它,它点它点它点它是不是都会发生改变呀。所以这个就是北京大兴区是吧,来吧,那这个时候就发生改变了,来就这一块。北京。
09:00
北京就到哪,就到这了。是不是,哎,然后怎么着啊,紧接着大兴区。来。再来一个。大兴区。这个。哎,是不是到这了呀。对吧,哎,再来一个是不是还有一个叫1212什么什么什么什么邮编是不是,哎这个呢。邮编。是不是就?到这个位置上了。好了,那这样的话,这个程序就到这儿啊,内存图到这儿了,那么接下来呢,User user等于new,一个user等号的右边先执行,先把user对象造出来。把user对象造出来,你找到user user里边有什么呀?有I didd是零呗,这个是none呗,这个是none呗,对吧,这两个是不是都是none啊,因为是引用数据类型,引用数据类型,这是none,这是none默认值嘛,这个默认值是零,所以把一个对象造出来之后呢,就长什么样呢?哎,就长这个样子啊,你不要随便来啊,走一步画一步啊,走一步一步来。
10:03
嗯。我们这块呢,应该是有一个对象的。各位啊,这个对象是一个什么呀?是一个user对象。啊,User对象。User类型对象啊,然后这个user里边有什么呢?哎,有一个这个。一个这个啊,有一个这个。是不是,哎,那这个是什么呢?哎,是int类型的ID。Int类型的ID,它实际上是什么是。对吧,来紧接着。紧接着有什么呢?String user name。是none。那么也就是说,这个位置实际上是什么呀?是string username。对不对,哎,String username这个username呢,它是none。然后呢,还有一个叫什么呢,叫做。
11:04
Dress a DDR。这个位置啊,注意看了。Address a DR。Address a DR。啊,这这个也是什么那。各位啊,也是,那么接下来呢,我们继续再往下看啊,那么这个对象一旦创建出来之后呢,通过等的方式给了UU这个局部变量,各位。U是一个局部变量,是在main方法里的局部变量user u user u呢,实际上是在这儿。啊,然后呢,这个u.u呢,它的局部变量,这个局部变量里面保存了一个内存地址是吧,这就是那个U。这就是那个U啊,然后呢,这个地方的内存地址可能比如说啊举个例子对吧,0X2222是不是,而这个0X2222是谁呢?哎,是他。
12:01
指向的对象是这个对象。啊,指向这个对象,这个对象。好了,那么接下来呢,我们再往下这个程序,应该是就输出我们这个u.ID对吧,u.u和u.ID点。那么u.ID user.username这个都是谁?u.ID是它u.username是它U点呃,A drr啊,这个单词,你看这个单词叫ADR啊。ADR,这叫username是不是?哎,这个叫ID,那么是不是就是铃铛铛啊?那么这块是不是就是0NONE none啊是不是好,那么现在我们来看看运行一下各位啊,运行一下Java去运行test走好大家看第一个是不是零铛铛,是不是到这这个零铛当是谁出的,是不是这啊这是不是零铛铛没问题吧,那接下来就继续来u. IDu.u.name u.ADDR好u.ID好处等于1111。
13:01
快看好了。优点ID等于什么呀?等于1111。那么这个1111啊,其实就把这个地方变了,就这就不是零了,那么紧接着呢,它的u.u的name等于张三,那就意味着我们这个位置上在不是none了,明白吗?哎,就哪个位置呢,这个位置就不是none了,他是谁啊叫张三,那张三呢,就把谁给给他放上去了呀。哎,就把这块的把上面这个给它盖住了,没了,那么接下来我们继续再往下呢,是什么呢?是u.ADR。u.ADR是这个单词,就是这个空间,就是这一块的空间,给它抹掉了,抹掉了啊,没了,把谁放进去了,大家看这个是A呀,各位。把A给它放进去了,A是谁?是他呀。A,是他呀。那是不是说把A里边的保存的这个东西,是不是原封复制了一份传过去了呢?
14:08
如果说传过去了,那么这个地址指向这个对象,那么现在的这个地址是不是也指向这个对象呢?因为你是地址啊。地址指向这个对象,你这个地址不也是指向这个对象吗?对吧。是不是这样的呀。这个图是不是这样的?0X1478是不是传过来了,为什么0X1478传过来,因为你这个位置是不是A通过等号的方式,A通过等号的方式是不是付过去了,付给谁的u.a.u是谁啊?U是它呀,点A是这个名字呀,点ad这个方框里边存一个什么东西,它等号的右边说的很清楚,等号右边是A吗。
15:03
A是谁呀?A,不就是它吗?它里边不是0X1478吗?1478,哎,给它扔过来不就是这个吗?这个地方是不是指向了它呀。对吧,你看就相当于内存图就变成这样一个内存图了。啊,内存图变成这样的内存图了,好,我不知道大家理解不理解什么意思啊,啊这个东西呢,我问大家先理解理解不理解这个啊,先分析一下理解是否理解这个程序啊。是否理解这个?是否理解这个?是否理解以下代码int a别A了TX等于100 int类型的Y等于X告诉我。这个等号是把X的什么东西给了Y?来,各位告诉我这个程序是什么意思?这程序什么意思,各位?
16:05
你给我解释什么意思,这意思啊。这个等号赋值把X给了Y,是把X里边什么东西给了Y?是把X给了Y,还是把里保存这个东西Y?哎,所以这个代码如果大家理解的话,这个等号代表负值嘛,等号啊代表负值运算。对吧,负值。中有一个值对吗?好,这个单词你看叫赋值对吗?负值对吗?各位,哎。X里边的值是多少啊,100。就是X变量中的值是100。
17:00
将100复制一份对吗?给谁?给Y是不是?是不是将100复制一份给Y,将X里边保存的这个100这个值。复制一份给了Y,对吗?是表示,表示什么意思啊?将X变量中保存的值100复制一份给谁?给。We。是吧,哎,那如果你这个理解的话。基本数据类是这样,引用数据类也是这样的。啊,那是否理解以下代码呢,我们把它拿过来啊,我再给大家写一个程序,那这块呢,假如说我们叫address。啊,Address k等于new什么呀?哎,那address m等于K,告诉我这是啥意思?
18:11
这行代码等同于什么,各位?这行代码是不是等同于后边这个对象,它是个内存地址是0X1111吧,假如说。其实这行代码就等同于这个,因为你扭出来一个对象之后,这个K变量里边保存的是这个对象的内存地址。注意,那K通过等号的方式付给M是把什么给付过去了,各位。X给Y的时候是把X里保存的,这个一是过了。100是不是复制了一份给了Y了?那同等道理,如果K要通过等号的方式付给M的话,是不是相当于K把K里边保存的这个0X1111复制了一份给了M了?是不是一个道理?各位啊,没有什么引用传递,没有什么值传递这一说我告诉你,其实在Java当中只有一种语法规则,就是值传递,就是值咋了?内存地址就叫值不行吗?内存地址就是个值行不行?各位,这个100它是个值对吗?0X111,这个内存地址它是不是一个值啊?它是不是也是个值啊?
19:14
各位同意我的这个说法吗?你不要搞什么引用传递,这传递那传递的,你不用管这个,你只要把握住一点,Java中有一个语法规则,如果在赋值的时候是一定是将变量里边保存的这个东东啊,把变量里边保存的这个东东传过去,一定是这样的,没有什么什么引用传递,这传递你不要搞那么复杂,Java中只有一种语法规则,它不会因为说你的类型是这种,我就给你一个语法规则,类型是这样,我就给你个语法规则,其实并不是这样的啊,说到本质上,实际上通过等号传递的时候,传的一定是变量中保存的这个东西给它传过去了,变量里边保存的这个东西给它传过去了,一定是保存的这个东西传过去了,各位啊,这个你一定要理解。这个要理解,你只要记住一点,这个规律是一样的,规律是一样的,各位啊,这个规律是什么?Int X等于100 X里面保存的不不过是个数字100喽,那那我X传过去,实际上是把X里边保存的这个100复制了一份传给了Y,对不对?那么呃,转K等于0X1111,那K是不是一个变量,这个变量里边是不是保存了一个一个0X121111的这样的一个一个东西啊,那么K通过等号的方式付给M,实际上是,实际上并不是把K给了M,不是把K给了M,这个X也不是给了Y啊,不是把X给了Y,是把X保存这个东西给了Y,这个呢,同样一样是把K里边保存的这个东西保存这个东西给了M。
20:42
明白吧,明白吧,明白这意思吧,实际上这里啊,这里表示将K变量中保存的这个0X1111复制了一份,传给了谁啊,传给了M变量。传给了M,变量传给M。
21:01
对吧,那我问你那这个呢。那这个呢。那这个呢,A是谁?各位A是谁?是。AAA是不是一个对象,好,在内存图上大家看A是不是它零里边是不是0X11478。1478对不对,那这个1478是不是就扔过去就行了,是不是把1478传过去了,是不是把1478复制了一份放到这儿了。一个道理啊,一个道理,把A嘛,通过等号的方式是不是附上去了,是不是把A通过等号的方式附上去了呀,你付给u.ADR啊,你U是谁呀?你优是它呀,它的ad drr不就是这个吗?它的ADDR这个空间里边存的这个东西是把A传过来了,A传过来实际上是把A变量里边保存的这个东东给它传过去了啊0X1478传过来就是,哎,复制了这个0X178,复制一份之后翻过来0X1478,那0X1478我问你是不是指向了这个对象。
22:01
那你这个0X178指向的是这个对象,你这个0X178是一个内存地址,你这个内存地址不也是不也是他吗?不也是他吗?对吧,是同一个对象啊,是同一个对象,是这样对吧?那么接下来我问大家要我们想知道张三是哪个城市的。张三?谁是张三?谁是张三?这个人是张三对吧,张三这个人是哪个城市的对吗。那能不能这样的优点?ADDR。然后再继续点。大家看啊,这个程序能不能这样写。就说城市,我输出。u.ad.r是谁?是谁?他对吗?是。优点ADDR能不能继续往后带点呢?
23:01
可以吗?因为你这个里边保存的是这个对象的内存地址,你优点ad点你你这个地方有个箭头是通过它能找到他的,你这个位置有个箭头,是不是通过它可以找到它呀。对吧,所以说你这个位置是u.a是继续。点C就是这个程序是不是可以继续往后点CT。对吧,u.a点吗。u.ad点咱捋捋啊,各位问一下U是谁?找呗。我问大家一个问题,不通过内存图,你能不能点儿出来,我觉得你不画内存图其实也可以出来。怎么出来来分析一下啊。是他的吗?他是谁,User?对不对,好,那U就是user。
24:00
User里边有个a.user来打开这个类。U的这个里边有一个ADDR对吗?所以U点什么ADR是不是好ADR的类型是什么address对吧?好,再继续往下找,大家看,呃,Dress里边有没有一个city啊。诶,你看是不是就是U就是user。u.ADDR,就是U点里边有没有这个ADDR,发现U点里边确实有这个变量叫ad,你u.ADDR之后,你发现ADDR啊,它的类型是什么呀?Address类型,但是你发现address这个类型里边确实有个变量叫,所以大家想想一想,想象一下这里是不是就可以u.ADR之后,哎,再去点CT,因为u.ad drr。就是个啥。点A点就是。对吧,那你address里边有啥呀,你看看address不是有啊,所以你这边是不是就可以优点ADR之后点啊。
25:04
这个。是前面这一堆的对吗。那你这个是谁呀?是他在哪里?那你优点ADR是不是一个address?来U点点是不是有个address。是不是,哎,所以你就会这样做呀。对吧,那这个是不是就可以放到这儿啊。是哪个城市的来?是不是这个城市的。张三是这个城市的,对吗?u.u name是不是张三,张三是u.ad点点CT城市的对吧?所以我们再来看Java c去编译Java去运行这个程序,是不是张三是北京城市。对吧,北京市的嘛。是不是,哎,就这样一个一个一个过程好了,我不知道大家理解不理,这个能不能拆分开各位优点ADR。City。
26:01
这行代码能不能拆?这一行代码可否拆分呢?那当然可以,优是谁,各位?U是它点id.R是不是它点点U的name的类型是什么对吗?点ID类型是不是in呀,你点ID,比如点ID吧,咱们尝试一下点ID是不是in,来各位看好了啊,u.ID是不是一个int?这个理解不,各位。点ID是一个这个理解。各位理解的话,打个一打个一各位啊。u.ID的类型是int。我点ID给一个特型变量行吗?没问题对吧。是不是,哎,没问题,好,那现在告诉我u.ADDR就把这行代码拆分一下嘛,对不对?u.ad点是什么类型。
27:03
你优点ID是int类型啊。u.ADD是什么类型啊?u. ADDu.ID是int类型。u.ad点是什么类型?Address。所以这块是不是一个address啊。是address,这个名叫ad吧,得得了,叫ad啊,Ad得了。是吧,好,那我问大家一个问题,Address是个ad对吧,Dress这一块。有没有这个属性。所以ad是不是可以点CT啊?Ad是不是可以点CT啊,因为ad是个address啊。ad.c吗?ad.c之后的类型什么类型吧。所以这边是不是一个string啊。
28:05
住址。对吧,set.out点打印输出什么呀?叫做住址吗?你这一行代码其实可以拆分成,拆分成这两行。u.a drr点可以继续往下点C是因为什么?是因为你u.ad drr的返回值类型是什么呀?Address,而你的address里面确实有一个C这样的属性。你u.ADR反馈是ad,然后ad再去点CT,是不是就和u.ad点点CT是一个效果?只不过这两行代码是不是变量稍微多点。如果你这么写,是不是省变量,节省变量?u. adr.CT是不是节省变量啊?拆分成下边这个代码,拆分成这两行代码,是不是多了两变量,是不是等于这里多了个变量去接收这个,然后这里又多了个变量去接收这个呀?是不是多了两两个变量啊?
29:03
对吧,拆分成拆分成以下代码和以上效果完全相同,原理完全相同,不同的是以下代码多了。两个变量吗?这个变量是u.ADR嘛?然后呢,Ad点什么呀,C吗。是不是啊,有ad.cd啊,付给这个变量,那最后把这个输出,那你u.ad点不就是ad嘛,那既然是ad,你把这个拿过来放,这不就完事了吗。对,你想想这个ad是不是就是它。他拿过来放这儿不就完事了吗?对吧,诶这这是拆分的啊,拆分开拆分开就是这样的。u.a点。哎,我觉得大家别迷糊啊,找规律,找规律就是里边你你你你如果到现在为止,你啥也没听懂,各位啊,在现到现在为止你啥也没听明白,你也不会画图,也不会这样,不会,那我告诉你,你你记住一句话就行。
30:11
就是里边有什么可以点什么。就里边有什么,你就可以点什么可以。对吧,你user里边有什么,有这个ADDR,你就可以点ADDR,点完ADDRDR是啥呀,是address address里边它有啥,就能把它点上,我觉得。我觉得是这样,各位啊,就是到目前为止,你如果什么也没有听明白,图也不会画,我还能不能学这个东西,有没有什么窍门你呀,记住一点就行啊,就是到目前为止吧啊,如果什么也没听懂,怎么写代码,记住一个啊。一个。就行,一个知识点就行啊,就行,可以后期慢慢学习画图啊,就是记住一个知识点就行,哪个知识点就是说这句话啊,记住一句话里面有什么就能点什么。
31:16
有同学里边有什么就能点什么。如果不加点CT,哎呀动你你这现在回答有点早啊,有点早,这个这个问题现在不答啊。先不答这个问题。不是类名加点啊,里面有什么就能点什么。这里说说点什么,一定要记住一点啊,是通过引用点什么啊,通过。所有的实例变量。或者叫属性,都是通过引用点来访问的。我再强调一下各位啊,system.out点打印,如果你硬要这么干,我告诉你,不对啊,User里边有ID,你偏偏就在这干啥,点ID不行。
32:10
不,不是这个意思,你再看看编译是不是报错了。第12行是不是报错了?是不是第12行不允许你这么访问,编译报错了,报错啊,报错了。ID是什么?是实例变量,必须通过什么?哎,必须先创建对象,通过引用点的方式访问。啊,通过引用的方式。这不是引用,这是类名。这是类名引用是谁?必须得通过引用啊,什么叫引用?U的U的又一个U的U叫引用,U是引用,明白优是引用啊,优是引用。
33:12
好,我问大家个问题啊,大家一起答啊,谁能答出来谁答啊?引用和对象怎么区分?引用是啥?对象是啥?答下来对象是啥?引用和对象有什么区别?啊。对象是累。错了啊。这个就叫对象,这叫对象啊。这个叫引用。
34:01
这个叫引用啊。对象是堆里边出来的,叫对象。啊,所以这一块呢,我还得再强调对象是啥堆里溜出来的。啊,错了,下边这个啊,对象是啥?堆里用出来的,引用是啥?是存储对象内存地址的一个变量。经典吗?精辟吧。引用是啥?是存储对象内存地址的一个变量,就叫引用。就只要这个变量里面存的是对象内存地址,这个变量就被叫做引用,就是说通俗一点啊,通俗一点就是只要这个变量中保存的是一个对象的内存地址。那么这个变量就叫做引用。
35:04
对象是你堆里边拗出来这个东西,这叫对象,这叫对象前面这叫引用啊,这叫引用。好了。各位。这个我就说到这儿啊。
我来说两句