Java中的数组及其在内存中的存储方式

12
我正在尝试理解Java中的数组设置。为什么在创建数组后,必须为每个对象初始化空间?它如何以这种方式存储在内存中:
[object][object]

或者像这样:

[*class]->[object]  
[*class]->[object]
换句话说,到底是在内存中实际发生了什么。 array[0] = new class()只是返回一个对预留内存位置的引用吗?class[] array = new class[10]语句创建了类似于10个指针的东西,稍后由new语句分配给它们吗?

3个回答

19

在Java中,数组存储两种类型的数据:原始值(如int, char等)或引用(也称为指针)。

因此,new Integer[10]只会创建10个Integer类型的引用空间。它并不会创建10个Integer对象(甚至不会为10个Integer对象释放空间)。

顺便提一下,这正好是字段、变量和方法/构造函数参数所使用的方式:它们只存储原始值或引用。


1
原始数据类型的数组和对象数组的存储方式在内存方面有区别吗? - rubixibuc
3
由于原始值没有引用,它们的值本身存储在数组中,而不是存储引用。 - Joachim Sauer
1
长度怎么办?Java中的数组知道它们的长度。那不是存储在某个地方吗?还是只有编译时才能知道? - GlenPeterson

7

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

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

是:

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

因此,当你执行以下操作时:

Person[] ps = new Person[5];

你正在预留一个含有5个Person对象引用的数组。接下来,你需要创建每个真实的人并将每个引用分配到数组中的一个位置。
编辑:上述代码的(几乎)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[0]到p[length-1]? - rubixibuc
是的。就像这样。在我的示例代码中,ps是数组。它也是一个引用(位于堆栈中),指向数组结构(位于堆中)。数组结构将保存对五个Person对象的引用。我会添加C/C++翻译 :) - helios

0

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

[对象引用][对象引用]

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

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


实际上,它类似于 OP 问题中的第二个示例。 - naXa stands with Ukraine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接