Java中的数组以及它们如何存储在内存中

Posted

技术标签:

【中文标题】Java中的数组以及它们如何存储在内存中【英文标题】:Arrays in Java and how they are stored in memory 【发布时间】:2011-07-30 16:22:45 【问题描述】:

我正在尝试了解 java 中的数组设置。为什么必须在创建数组后为数组中的每个对象初始化空间。它是如何存储在内存中的:

[object][object]

或者像这样:

[*class]->[object]  
[*class]->[object]

换句话说,在内存中实际做了什么。 array[0] = new class() 是否只是返回对内存中保留位置的引用,而 class[] array = new class[10] 语句会创建类似于 10 个指针的内容,这些指针稍后由新语句分配?

【问题讨论】:

Java Array is stored in stack or heap? 的可能重复项 【参考方案1】:

Java 中的数组存储以下两种内容之一:原始值(intchar、...)或引用(也称为指针)。

因此,new Integer[10] 仅为 10 个 Integer 引用创建空间。它确实创建 10 个Integer 对象(甚至为 10 个Integer 对象创建可用空间)。

顺便说一句,字段、变量和方法/构造函数参数的工作方式完全相同:它们也只存储原始值或引用。

【讨论】:

基元数组的存储方式与对象数组的存储方式是否存在内存差异 由于没有对原始值的引用,因此值本身存储在数组中而不是引用中。 长度呢? Java 中的数组知道它们的长度。那不是存放在某个地方吗?还是那只是编译时的事情?【参考方案2】:

如果您熟悉 C/C++ 您可以将 Java 对象引用视为指向对象的指针(或指向结构的指针)。所以:

Person p = new Person();
p.setName("Helios");

是:

声明一个指向 Person 结构的 p 指针(在堆栈中) 为 Person 结构保留内存并对其进行初始化 将其地址分配给 p 对 p 引用的对象执行 setName 方法

所以当你在做的时候:

Person[] ps = new Person[5];

您正在保留对 Person 的 5 个引用的数组。接下来,您必须创建每个真实的人并将每个引用分配给数组中的一个位置。

编辑:之前代码的(几乎)C/C++ 版本

class Person  ... ;
typedef PersonStruct* Person; // I don't remember if this declaration is ok
Person p = new PersonStruct();
p -> setName(...);

Person[] ps = new Person[5]; 
// ps is a variable in the stack pointing to the array in the heap
// (being the array five references to the PersoStruct)

你可以这样做

ps[3] = p;

【讨论】:

所以这几乎就像您正在创建一个人 *p[] 数组,然后在整个 p[length-1] 中一一分配给 p[0]? 是的。就像这样。在我的示例代码中, ps 是数组。它也是对数组结构(位于堆中)的引用(位于堆栈中)。数组结构将保存对五个 Person 对象的引用。我将添加一个 C/C++ 翻译:)【参考方案3】:

数组是连续的内存空间,所以它们看起来更像你的第一个草图:

[object-reference][object-reference]

array[0] = new class() 将在array[0] 中存储对新创建对象的引用。

class[] array = new class[10] 将创建一个包含十个空槽(或十个空引用)的数组。

【讨论】:

其实它类似于OP的问题中的第二个例子。

以上是关于Java中的数组以及它们如何存储在内存中的主要内容,如果未能解决你的问题,请参考以下文章

在java中初始化数组时的堆栈和堆内存[重复]

JAVA中Vector怎样存放一个动态的二维数组

多维数组如何存储在内存中? [复制]

Java 数组和链表的区别以及使用场景

JAVA内存模型与线程以及volatile理解

Java数组在内存中是啥样的