Java中类和对象的分配机制
作者:互联网
前言
上一篇的续集 Java对象在内存的布局
先看一段代码回答引出一问题:
class Dog
{
int age ;
String name ;
String color ;
}
public class Object
{
public static void main(String[] args)
{
Dog dog1 = new Dog();
dog1.age = 3;
dog1.name = "小黑";
dog1.color = "黑色";
Dog dog2 = dog1; //该语句执行时候发生了什么
}
}
问 Dog dog2 = dog1; 该语句执行时候发生了什么?
首先一步一步的跟着我的思路走着先。(下面的过程会有图帮助理解)
1.先执行第一段代码:Dog dog1 = new Dog();
- 首先先new 一个Dog对象,此时会加载Dog类的信息,什么信息呢?也就是属性信息和方法信息。
- 加载到哪里呢?加载到堆空间中,所以就会在堆中开辟一段内存空间来存放这些信息,开辟内存空间必定有一段地址,该空间里面有什么呢?在本例案例中,堆中有属性age,name,clolord的信息。
- 一开始的时候,age,name,color中是有默认初始值的,该默认初始值是由系统决定的,对于int的类型默认初始值是 0,对于String的类型默认初始值是 null。所以在本案例中的age = 0,而 name,和color 中是 null。
- 当加载完信息,和默认初始化后,就会给dog1这个对象赋值,所以该dog1对象会在栈空间开辟一段空间用于接收类中的属性值。赋值赋的是什么呢?其实给dog1对象的是对在堆空间开辟出来的那段空间地址。也就是dog1会指向这段堆空间。此时第一段代码指向完毕。
- 如下图:
2.执行第二段代码: dog1.age = 3;
-
即在开辟的堆空间的age属性赋值为3,把原本为0的值,赋值为3.
-
如下图:
3.执行第三段代码:dog1.name = “小黑”; -
此段代码也是在 name 中直接赋值为 小黑 吗?如果是这么想你就错了,这比第二段代码执行的时候复杂一点,多了一个步骤。系统看到这段代码,首先判断 “ 小黑 ”是字符串常量,其次会把字符串常量的值保存在方法区中的常量区,那你要保存在别人的地盘,自然而然需要一段空间,一旦有了空间就必定有地址。所以呢就会发生很特别的事情。在堆区中的name不是保存“小黑”这个值,而是保存小黑中的地址,这样你需要“小黑”这个值,就可以通过地址找到啦。(第四段代码和第三段代码一样滴执行机制)
-
如下图:
-
4.理解上面的你就不难理解第五段代码:Dog dog2 = dog1;执行的时候发生了什么。对,就是很简单的把,dog1赋值dog2。可是怎么赋值呢?是给dog2开辟一段和dog1一样大小的新空间吗?其实不是,你想想,假如是这样,那不得耗费多少内存空间呀。其实本质是通过保存其dog1中的地址即可,这样dog2对象也会指向dog1中的空间。
如下图:
总结
Java中创建对象的流程分析:
1.先加载 类中的信息(只会加载一次)
2.在堆中开辟空间,执行默认初始化。
3.在栈中开辟一段空间存放对象,该对象指向堆空间。
4.给属性赋初始值。
接下来我出几道练习题问问你,是否真的懂了。
- 请问执行这段代码 dog2.age = 5;dog1中的age有没有改变呢?
答:改变了,因为这两个对象 dog1 和 dog2 都指向同一段的内存空间,这样改变dog2的数据,就会改变dog1中的数据。
- 假如我给执行这段代码 dog2.age = 5; dog2 = null; 请问我想输出 dog1.age 的值,和dog2.age的值是什么?
答:dog1.age = 5;dog2.age 会抛出异常,即无法输出。
有人可能会蒙圈了,怎么第一题不是说 dog1 和 dog2 都指向同一段的内存空间,那你既然给了dog2赋值为 null,那dog1肯定也是 null 啊。为啥会有 dog1.age = 5 ? 兄弟们,别急?听我慢慢给你解释解释。确实:dog1 和 dog2 都指向同一段的内存空间。但,有个问题dog1 和dog2 有啥关系呢?它们两个都是独立的空间,存放的东西都是独立的,当你执行 dog2 = null;的时候,只是dog2 指向了null,不指向堆空间的内容罢了,而人家 dog1依旧还是指向 堆空间的内容呀,你改变了dog2,人家dog1却没有变,人家不忘初心呀。自然而然就是dog2指向了null,都没有堆的内容了,肯定输出不了数据。
到此,大概你也理解了Java对象的分配机制了,感谢观看。
标签:Java,name,分配机制,age,Dog,null,dog2,中类,dog1 来源: https://blog.csdn.net/m0_46606290/article/details/117620901