我正在尝试使用for循环初始化整数java数组中的对象,但是在for循环退出后数组元素为null。
public static void main(String[] args) {
Integer[] x = new Integer[1];
for (Integer xx : x) {
xx = new Integer(1);
System.out.println("inside for loop "+xx.toString());
}
System.out.println("why isn't this 1? " + x[0]);
x[0] = new Integer(2);
for (Integer xx : x) {
System.out.println("Not it's okay: " + xx.toString());
}
}
但是在for循环退出后,数组元素为null。这是输出:
inside for loop 1
why isn't this 1? null
Not it's okay: 2
为什么这个for循环的行为与for (i=0;i<1;i++){x[i]=1;}
相同?
答案 0 :(得分:5)
出于完全相同的原因,这不起作用:
Integer a1 = null;
Integer a2 = a1;
a2 = new Integer(1);
System.out.println(a1.toString()); // Fails, a1 is still null
循环中的xx
不是对数组元素的某种引用;相反,它是一个变量,包含数组元素值的副本(在您的情况下为null
)。设置xx
的值只是设置其值,它对数组条目没有任何影响。
让我们通过以下代码:
Integer[] x = new Integer[1];
在记忆中,我们现在有类似的东西(忽略一些细节):
+−−−−−−−−−−−+ x[Ref22135]−−−−−>| Integer[] | +−−−−−−−−−−−+ | length: 1 | | 0: null | +−−−−−−−−−−−+
(x
内的“Ref22135”是一个名为对象引用的值,告诉JVM数组在内存中的位置。对象引用是值,就像基元一样我们处理对象的事实实际上与设置xx
不会影响x[0]
的原因无关,但由于你使用Integer[]
,我必须提及它。)< / em>的
现在,我们进入你的循环:
for (Integer xx : x) {
此时,再次忽略一些细节,我们有:
+−−−−−−−−−−−+ x[Ref22135]−−−−−>| Integer[] | +−−−−−−−−−−−+ | length: 1 | | 0: null | +−−−−−−−−−−−+ xx[null]
x[0]
(null
)的值已复制至xx
。
现在我们完成你的任务:
xx = new Integer(1);
这给了我们:
+−−−−−−−−−−−+ x[Ref22135]−−−−−>| Integer[] | +−−−−−−−−−−−+ | length: 1 | | 0: null | +−−−−−−−−−−−+ +−−−−−−−−−−−−−+ xx[Ref99845]−−−−>| Integer | +−−−−−−−−−−−−−+ | rawValue: 1 | +−−−−−−−−−−−−−+
如您所见,设置xx
中的值(“Ref99845”,对新Integer
对象的引用)对数组没有任何影响。
请注意,这与我们处理对象的事实无关,如果我们处理原语,它将完全相同:
int[] array = new int[1];
for (int entry : array)
{
entry = 42;
System.out.println(entry);
}
System.out.println(array[0]);
输出:
42 0
如果我们此时停止该代码:
int[] array = new int[1];
for (int entry : array)
{
entry = 42;
我们在记忆中看到的东西如下:
+−−−−−−−−−−−+ array[Ref56418]−−−−−>| int[] | +−−−−−−−−−−−+ | length: 1 | | 0: 0 | +−−−−−−−−−−−+ entry[42]
使用Integer[]
时唯一的区别是从x[0]
复制到xx
的值是对象引用而不是int。但没关系;它仍然是一个值,当从一个事物分配给另一个事物时,值总是被复制。 (复制对象引用只会复制引用,当然不是它引用的对象)。
答案 1 :(得分:1)
你不能通过使用增强的for循环来更改数组中元素的原因是它们是如何被去除的(JLS 14.14.2):
for(int i = 0; i < x.length; i++) {
Integer xx = x[i];
// you're working with a variable not with the i-th element
}
// is equivalent to:
for(Integer xx : x) {
//...
}
答案 2 :(得分:0)
您没有向数组添加值。 希望这对你有用,
Integer[] x = new Integer[1];
for(int i = 0 ; i<x.length ; i++){
x[i] = new Integer(1);
System.out.println("inside for loop "+x[i].toString());
}
System.out.println("why isn't this 1? " + x[0]);
x[0] = new Integer(2);
for (Integer xx : x) {
System.out.println("Not it's okay: " + xx.toString());
}
输出
inside for loop 1
why isn't this 1? 1
Not it's okay: 2
答案 3 :(得分:0)
你的例子中的主要问题是foreach循环的使用,它不像你期望的那样工作:
Integer[] ints = new Integer[5];
for (Integer a : ints) { // assign each element of the array into the temp variable "a"
a = new Integer(1);
}
这与:
相同Integer[] ints = new Integer[5];
for (int i = 0; < ints.length; i++) {
// reference "a" is pointing on the same place as reference stored in ints[i]
// which is null, so both are pointing on null address
Integer a = ints[i];
// reference "a" is now pointing on newly allocated address with Integer(1)
// but ints[i] is still null
a = new Integer(1);
System.out.println(int[i]); // prints null
System.out.println(a); // prints 1
}
如果要更改数组内容,则必须直接将值分配给数组:
for (int i = 0; < ints.length; i++) {
ints[i] = new Integer(1);
}
但是这对于每个循环都是不可能的,它总是将array[i]
复制到局部变量中。