00:00
那为了大家呢,能够更好的理解刚才我们说的这个事儿呢,咱们就得画这个内存解析了,所以下边这个问题呢,就是这个对象的内存解析。前面呢,我们在讲数组的时候呢,也画过这个内存解析,那那个时候画其实跟现在这个话呢,呃,都是呢,需要使用我们这个内存中的栈和堆这个结构了,咱们在讲数字的时候呢,也稍微提过一下,说这个内存这个结构呢,是什么样的情况啊,咱们说过一个简图啊,这块呢,稍微复杂的我们引进来一下,那关于这个Java虚拟机,它所规定的这个内存结构完整上来讲呢,是有这样的一个图示的。大家去网上找的话呢,一定可以找到这样一个图示,那么详细的关于这个内容的话呢,大家可以后期关注这个GVM这个内容就可以了,在这儿呢,我们根据咱们的需要呢,只讲解其中的部分情况啊,主要呢,我们关注的就是这个运行时数据区,那运行时数据区就是我们主要加载的数据呢,都在这里边的,那运行是数据区呢,又分成这样的五个部分,分成了叫方法区堆,虚拟机站,程序计数器,本地方法站这样的几个结构,那这几个结构里边我们重点关注的就是占堆啊,方法区呢,后边也会用得到啊,本地方法站这涉及到呢,我们调用一些本这个本地通过Java呢,我们调本地的这个C或C加加的这个类库啊,就叫本地方法的这个结构,包括本地这个库的接口这块啊,程序计数器啊,这个呢,就跟我们整个运行这个程序加载这个结构呢,就没有关系了,咱们呢,暂时也就先不提它啊。
01:36
那么在这三个结构当中,这里呢,叫虚拟基站。他其实就是我们通常所说的那个站。但通常所说的站是它不是这个啊,哎,这要注意,这叫虚拟基站,那虚拟基站这里边主要存放什么结构在这呢也有写,主要呢,我们就存放的叫局无变量。对,咱们提过这个事儿啊,再强调一下,存放呢,叫去物变量,什么叫去变量,一会儿我们展开呢,去准确的去给它定义去说明啊,那么对。
02:05
这是我们用的也是非常高频的一个结构,对呢,主要呢,就是来存放这个对象实例的,这里边这个对象呢,你可以理解成一个广义上的对象,既包括我们像刚才new person这样的对象,New的scanner这样的对象,也包括呢,像我们new的数组,哎,我们都把它称作叫做对象这个结构了,也就是说我们创建的真实的这个结构,这个对象的实体都在堆空间当中。哎,都在这个对空间当中啊,那么方法区,方法区的话呢,哎,它里边主要存放的结构,哎,这里提到了我们加载的类信息,然后常量,常量里边呢,典型的就是字符串常量池,还有我们的叫静态变量或者叫静态域啊,这样的一些结构都是在我们的这个方法区进行加载的。啊行,那这个图呢,大家主要呢,就是关注一下我画红色的这个结构。啊,这个文字就可以了,后边呢,咱们也不断的会去强调这里边儿这个结构该怎么去用的啊呃,后期呢,咱们讲到string的时候呢,会提到常量池,讲到static关键字的时候呢,会提到这个静态变量。
03:11
啊,就会用到这个方法去了,那目前的话呢,咱们主要用的还都是栈和堆行,那么咱们就来画一下刚才提到的这样的问题,这就是咱们这个叫对象的内存解析。行,那咱们刚才涉及到这个核心的代码呢,我这块呢粘一下啊,一个是它CTRLC。然后我们这样调了一下CTRLC。接下来,我们又new了一个。那这块呢,我们试着呢去输出了一下。哎,这个P2点内,好,这是它,然后接下来我们又造了一个P3。
04:07
P3呢,我们去改了一下age,好,我们就来看这样的一些代码呢,到底该怎么执行。放在这儿,目前的话呢,我们还用不着这个方法区,主要呢,就是涉及到这个栈和堆的结结构。这个我们把它这个跟代码其实没关系了啊,我就这样放到里边显得好看一点。行这样子,那这个瘦的话呢,就是我们说的这个站。战的特点还记得吧,先进后出,对。对。
05:00
好,这呢是我们这要用的这两个结构,首先我们看第一行代码person PE等于new,一个person,我们呢去造了个对象,那我们说过了啊,只要是new的结构呢,都是在堆里了,那就意味着我们这时候呢,需要啊在堆空间当中造一个你这个对象的实体。那这个对象实体的话呢,就会有个地址值,我们把它称作叫首地址值。对,就是我们也只关注它这个首地值值啊,后边这个数据在什么位置不关注,只要首地值值,首地值呢,我们用16进制的这个数据来表示啊,比如12AB,诶将这个数据呢,因为你看我们这个赋值操作啊,把你右边这个数据呢,附给左边了,其实这时候附过来的是一个地址,在债空间当中生明一个变量叫P。此时呢,我们这个P1实际上呢,是定义在may方法当中的,咱们这个代码都是写在may方法里的啊,May方法是一个方法,方法中的变量都是局部变量,方法中定义的变量都是局部变量,所以自然而然的呢,我们这个站里边存放的就是P的这个局部变量,然后呢,你这边是复制过来了,我就0X。
06:07
1AB。行,那通过这样的一个地址值占空间中的P1就指向了对空间中你造的这个对象实体,第一行代码还没完事,这个堆空间当中这个我们一会呢,讲这个属性的时候会提啊,咱们这个类在设计的时候呢,声明过三个属性,Name age和isma,这三个属性呢,不同于局部变量。哎,局部变量的话呢,是存在我们这个站空间中,我这个属性是存在于堆空间当中的,那也就在我们这个造好的对象里面,我有一个name,有一个age,有一个is没有。是这样的。啊是这样的,而且这个时候呢,都会考虑值的问题,呃,第一行代码还没完事,还在第一行这块啊,呃,这块呢,我们的name is没都没有赋过值,通过咱们刚才看这个。
07:12
这个P3,这是Tom p2的话呢,是个no,通过这呢,咱们能够知道这个它也有值,是不是这个nor啊对,这就涉及到一个默认初始化值了,咱们去总结一会儿啊,咱们先把这个事儿呢,先用一用,这呢是一个no,这个age呢,我们赋了一个一对,所以就写一,这呢没有符过值,所以又是一个默认值叫false,好,那到此为止,我们第一行代码呢,搞定了,就是在内存中呢,就是这样的一个结构,接下来我们通过占空间中的这个PE呢,我去调name,通过PE找到这个结构啊,然后调这个name,改成了to姆,相当于呢,是把这个闹给它干掉,改成了Tom。注意啊,这个我那会儿这个前几天复习的时候说过这个事儿,Tom实际上是不在这儿了啊,是在这个自串常量池在方法区的,像咱们现在这个中心呢,先不去研究那块儿啊,你先整体熟悉这个结构啊,我就先暂时呢写到这儿了,改成Tom,然后一直没有改成to。
08:23
诶注意这个true可得小写啊,这样呢是严格区分的,要写的好写成false,呃写成true,这样的话呢,我们这两行代码呢,就搞定了。再接着我们又了一个person,哎,就是相当于又重新造了一个P2对象,那又得是重新的在堆空间当中,我们去造一个对象实体,然后呢,有一个手提指值。哎,0X7788,比如说将这个地址值付给我们站空间中现在加载的P2。
09:02
0X7788。好,通过这个地址值占空间中的这个P2对象,就可以指向对空间中这个对象实体,哎,这两个代码还没完事,同样的道理,跟我们刚才这一行一样,它也有这样的一个呃值的情况。哎,我就拿过来了啊,注意不是从这复制的,这我只是为了省事,我这样拖过来了啊,这就是独立生成的一份,跟他没啥关系啊,跟你这里边就没啥关系了,哎,那到此为止呢,我们这一行代码呢,就也搞定了。那接下来我们呢,去输出一下P2点name p2点name,所以是no,哎,这就是我们刚才那会所说的,如果呢,我们创建了一个类的多个对象,这多个对象呢,都独立的拥有一套我们这个类的属性,你是你的,我是我的,你要汤姆,我这呢不是,哎这个注意不是了啊,但是这个一的话呢,因为咱们在造累的时候就说了,你这个A是一了,所以这时候呢,大家就都是一。
10:09
这是由于你这个生命类的时候决定的啊,哎,这呢也都是默认值了,行这个代码我们就搞定了,它的输出结果呢是个no,这样呢就清楚为什么在接下来呢,我们又声明了一个P3 P3呢是这个既然是一个局部变量了,新声明的,那我们就在占空间中给大家再声明一个叫P3。P3,那是拿PE赋的值。P附的值,P付过来的是一个地址值,其实就是你存什么我就传什么,你存的是个地址值,我就给你传一个地址值。好,那通过你传过来的这个地址值,我呢也指向了对对空间中的一个结构,那我就顺着我这个地址找的啊,我一找我就找到它了,所以此时呢,P3不能叫新创建了一个对象,只能顶多算一个新声明的一个变量啊,那此时呢,P1和P3实际上呢,是指向了对空间中的同一个对象实体。
11:08
哎,那所以说呢,我们通过P3我来修改这个A。把它改完以后,我们P一再去调,那自然而然的也是修改以后的,嗯,是。这样子。所以我们在通过这个PE去调一值呢,它就是十,哎这呢我们就解释清楚了,这就是我们所说的,这叫对象的一个内存解析啊,在这块呢,属性这个位置呢,这是咱们新的,相当于前面讲这个数组的时候是新的啊,只不过数组那块呢,就是你存在你里边的一个一个的元素了,咱这呢就存的是一个一个的属性,哎就这个意思,好,那这个结构呢,需要大家下来呢,能够自己的能够画出来。哎,去理解一下我们这个过程。
我来说两句