数组声明并将值分配给数组的各个插槽



我之前问过这个问题,把事情搞清楚了。 但是,我有一些疑问,解释如下:

让我们假设需要有一个包含 100 个元素的数组:

1) 声明数组:

Integer[] intArr;

2) 为 100 个整数元素分配内存,并将引用分配给变量

intArr = new Integer[100];

现在真正的疑问来了。

哪一种是为数组中的各个元素赋值的正确方法:

方法1:

intArr[1] = 1;

方法2:

intArr[1] = new Integer(1);

我的怀疑是我们已经为 100 个元素分配了内存,如果我们使用 方法 2 ,我们不是再创建一个内存区域并将它们分配给 intArr1 吗?

intArr[index] 是否保存引用的地址,或者实际对象是否可以放置在 intArr[index] 中。

希望能得到一些见解来消除这个疑问。

这两行在某种程度上是等价的。第一种使用自动装箱。它实际上直接等同于:

intArr[1] = Integer.valueOf(1);

不同之处在于,这可以多次重用对同一Integer对象的引用,而在第二种方法中,您正在创建新的Integer对象。您可以在此处看到差异:

intArr[1] = Integer.valueOf(1);
intArr[2] = Integer.valueOf(1);
System.out.println(intArr[1] == intArr[2]); // True, references to the same object
intArr[1] = new Integer(1);
intArr[2] = new Integer(1);
System.out.println(intArr[1] == intArr[2]); // False, references to the different objects

在所有情况下,数组的值都是引用。它们从来都不是对象本身。当您分配数组时,这将为 100 个引用创建足够的空间,并且这些引用最初都是null的。

如果你想要一个直接包含整数数据的数组,只需使用int[]而不是Integer[]

我的怀疑是我们已经为 100 个元素分配了内存,如果我们使用 方法 2 ,我们不是再创建一个内存区域并将它们分配给 intArr1 吗?

您在new Integer[100]中分配的内存用于数组将包含的 100 个对象引用,而不是它包含的对象。添加到数组时,由于它是对象数组,因此您仍然必须创建对象。

您的方法实际上本质上是相同的,因为编译器将通过Integer.valueOf(1)自动"框"方法1中的1,更改:

intArr[1] = 1;

intArr[1] = Integer.valueOf(1);

(即使不依赖于自动装箱,Integer.valueOf通常是获取Integer实例的更好方法,因为它可以缓存它们 [并且始终缓存 -128 到 127 的实例]。

让我们继续一些ASCII艺术:

当您执行以下操作时:

Integer[] intArr;

你的记忆中有这样的东西:

intArr[null]

例如,一个包含null的变量。现在,您为数组分配内存并将其分配给变量:

intArr = new Integer[100];

你会得到这样的东西:

+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
intArr[Ref21345]−−−−>| 整数[100] |  +−−−−−−−−−−−−−−−−+  | 0:空 |  | 1:空 |  |...            |  |99:空 |  +−−−−

−−−−−−−−−−−−+现在我们有空间存储 100 个对象引用;它们都是从null开始的。然后你做:

intArr[0] = 1;

编译器变成

intArr[0] = Integer.valueOf(1);

你会得到:

+−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−
intArr[Ref21345]−−−−>| 整数[100] |  +−−−−−−−−−−−−−−−−+     +−−−−−−−−−−+  | 0: [ref84651] |−−−−>|整数 |  | 1:空 |    +−−−−−−−−−−+  |...            |    |值:1 |  |99:空 |    +−−−−−−−−−−+  +−−
−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−

只是为了详细说明。

如果你说

int[] vals = new int[10];

您正在为 10 个整数分配空间。这意味着此处分配的内存为10* 32位。

Integer[] vals = new Integer[10].

此处分配的内存什么都没有(除了数组对象本身)。数组中的所有元素都是空的,并且不会携带任何内存。

所以当你这样做时

intArr[1] = new Integer(1);

new Integer(1)分配的内存和对intArr索引的引用,因此您实际上只分配一次内存。

即使你正在做

intArr[1] = 1;

它实际上自动装箱以Integer并存储该引用。

最新更新