(Java)关于内存分配的理解

妖精的绣舞 提交于 2020-01-28 03:51:47

(1)栈内存空间:保存所有的对象名称(更准确地说是保存了引用的堆内存空间的地址)
(2)堆内存空间:保存每个对象的具体属性内容。
(3)全局数据区:保存static 类型的属性
(4)全局代码区:保存所有的方法定义

一、从数组角度理解内存分配

拿数组操作来说,在栈内存中保存的永远是数组的名称,只开辟了栈内存空间的数组是永远无法使用的,必须有指向的堆内存才可以使用,要想开辟新的堆内存就必须使用new关键字

这也就解释了为什么对于数组的声明都要写上一个“null”?

int score[] = null;
score = new int[3]
// 或者:int score[] = new int[3];

因为数组属于引用数据类型,对于引用数据类型来说,其默认值就是null,表示暂时没有指向任何的内存空间

比如:
在这里插入图片描述
这里一个数组在开辟了堆内存之后,将在堆内存中保存数据,并将堆内存的操作地址给了数组名称score

此时也只是将堆内存的使用权交给了对应的栈内存空间,而一个堆内存空间可以被多个栈内存空间指向
比如一个人可以有多个名字,人就相当于堆内存,名字就相当于栈内存
在这里插入图片描述

二、从字符串角度来理解内存分配

public class Test{
    public static void main(String[] args) {
        String str1 = "hello";
        String str2 = new String("hello");
        String str3 = str2;
        System.out.println("str1 == str2 -->" + (str1==str2));
        System.out.println("str2 == str3 -->" + (str2==str3));
    }
}

在这里插入图片描述
由结果可知,虽然程序String中的内容都是一样的,但是比较结果却不一致。
这是因为==使用地址值进行比较的
在这里插入图片描述
从图中我们可知,每个 String 对象的内容实际上都是保存在堆内存之中的,而且堆中的内容也是相同的。但是对 str1 和 str2 来说,内容分别保存在不同的空间,所以即使内容相同,地址的值也是不同的

一个字符串就是一个 String 类的匿名对象,而如果使用 new 关键字,不管如何都会开辟一个新的空间,此空间的内容还是 hello。所以String str = new String("hello")实际上是开辟了两个内存空间

匿名对象就是已经开辟堆内存空间并可以直接使用的对象。

因此当我们对于字符串进行操作时,一般采用直接赋值的方法完成,而不考虑采用构造方法的方式完成

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!