我之前问了this问题并清楚了解问题。 但是,我有一些疑问,解释如下:
让我们假设需要一个包含100个元素的数组:
1)声明数组:
Integer[] intArr;
2)为100个整数元素分配内存,并为变量
分配引用intArr = new Integer[100];
现在出现了真正的疑问。
哪一种是为数组中的各个元素赋值的正确方法:
intArr[1] = 1;
intArr[1] = new Integer(1);
我怀疑是我们已经为100个元素分配了内存,如果我们使用方法2,我们是不是再创建一个内存区域并将它们分配给intArr 1?
intArr [index]是否保存引用的地址或实际对象可以放在intArr [index]中。
希望能有一些见解来澄清这个疑问。
答案 0 :(得分:11)
这两行有些相同。第一个使用自动装箱。它实际上直接等同于:
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[]
。
答案 1 :(得分:5)
我怀疑是我们已经为100个元素分配了内存,如果我们使用方法2,我们是否还要创建一个内存区域并将它们分配给intArr1?
您在new Integer[100]
中分配的内存是针对数组将包含的100个对象引用,而不是它包含的对象。添加到数组时,由于它是一个对象数组,因此您仍然需要创建该对象。
你的方法实际上基本上是相同的,因为编译器会自动地" box"方法1中的1
通过Integer.valueOf(1)
,更改:
intArr[1] = 1;
到
intArr[1] = Integer.valueOf(1);
(即使不依赖于自动装箱,Integer.valueOf
通常是获取Integer
实例的更好方法,因为它可以缓存它们[并始终缓存-128到127的实例]。)< / p>
让我们用一些ASCII艺术来完成它:
当你这样做时:
Integer[] intArr;
你在记忆中有这样的东西:
intArr[null]
,例如,包含null
的变量。现在为数组分配内存并将其分配给变量:
intArr = new Integer[100];
你得到这样的东西:
+−−−−−−−−−−−−−−−−+ intArr[Ref21345]−−−−>| Integer[100] | +−−−−−−−−−−−−−−−−+ | 0: null | | 1: null | | ... | | 99: null | +−−−−−−−−−−−−−−−−+
现在我们有空间存储100个对象引用;他们都从null
开始。然后你做:
intArr[0] = 1;
编译器变为
intArr[0] = Integer.valueOf(1);
你得到:
+−−−−−−−−−−−−−−−−+ intArr[Ref21345]−−−−>| Integer[100] | +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−+ | 0: [Ref84651] |−−−−>| Integer | | 1: null | +−−−−−−−−−−+ | ... | | value: 1 | | 99: null | +−−−−−−−−−−+ +−−−−−−−−−−−−−−−−+
答案 2 :(得分:1)
只是详细说明。
如果你说
int[] vals = new int[10];
您正在为10个整数分配空间。这意味着此处分配的内存为10* 32
位。
Integer[] vals = new Integer[10].
这里分配的内存不算什么(除了数组对象本身)。数组中的所有元素都是null,并且还没有携带任何内存。
所以当你这样做时
intArr[1] = new Integer(1);
为new Integer(1)
分配的内存以及intArr
索引的引用,所以实际上只分配了一次内存。
即使你正在做
intArr[1] = 1;
它实际上自动装箱到Integer
并存储该引用。