java foreach循环中的数组引用
我试图使用for循环初始化java整数数组中的对象,但是for循环退出后数组元素为nulljava foreach循环中的数组引用,java,arrays,generics,foreach,Java,Arrays,Generics,Foreach,我试图使用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()); } S
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循环的行为与i=0的行为不一样;我完全出于同样的原因,这不起作用:
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]−−−−−>| Integer[] |
+−−−−−−−−−−−+
| length: 1 |
| 0: null |
+−−−−−−−−−−−+
xx[null]
这给了我们:
+−−−−−−−−−−−+
x[Ref22135]−−−−−>| Integer[] |
+−−−−−−−−−−−+
| length: 1 |
| 0: null |
+−−−−−−−−−−−+
+−−−−−−−−−−−−−+
xx[Ref99845]−−−−>| Integer |
+−−−−−−−−−−−−−+
| rawValue: 1 |
+−−−−−−−−−−−−−+
输出:
42
0
我们记忆中的东西看起来像:
+−−−−−−−−−−−+
array[Ref56418]−−−−−>| int[] |
+−−−−−−−−−−−+
| length: 1 |
| 0: 0 |
+−−−−−−−−−−−+
entry[42]
使用Integer[]时唯一的区别是,从x[0]复制到xx的值是对象引用,而不是int;它仍然是一个值,当从一个对象分配到另一个对象时,值总是被复制的。复制对象引用当然只是复制引用,而不是它引用的对象。原因与此不起作用完全相同:
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]−−−−−>| Integer[] |
+−−−−−−−−−−−+
| length: 1 |
| 0: null |
+−−−−−−−−−−−+
xx[null]
这给了我们:
+−−−−−−−−−−−+
x[Ref22135]−−−−−>| Integer[] |
+−−−−−−−−−−−+
| length: 1 |
| 0: null |
+−−−−−−−−−−−+
+−−−−−−−−−−−−−+
xx[Ref99845]−−−−>| Integer |
+−−−−−−−−−−−−−+
| rawValue: 1 |
+−−−−−−−−−−−−−+
输出:
42
0
我们记忆中的东西看起来像:
+−−−−−−−−−−−+
array[Ref56418]−−−−−>| int[] |
+−−−−−−−−−−−+
| length: 1 |
| 0: 0 |
+−−−−−−−−−−−+
entry[42]
使用Integer[]时唯一的区别是,从x[0]复制到xx的值是对象引用,而不是int;它仍然是一个值,当从一个对象分配到另一个对象时,值总是被复制的。复制对象引用当然只是复制引用,而不是它引用的对象。您没有向数组添加值。 希望这对你有用
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());
}
您没有向数组添加值。 希望这对你有用
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());
}
无法通过使用增强的for循环更改数组中的元素的原因是这些元素的分解方式:
无法通过使用增强的for循环更改数组中的元素的原因是这些元素的分解方式:
您的示例中的主要问题是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);
}
但是,对于for-each循环,这是不可能的,因为它总是将array[i]复制到局部变量中。您的示例中的主要问题是使用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);
}
但是对于for-each循环,这是不可能的,因为它总是将数组[i]复制到局部变量中。我认为这是一个关于for-java-each循环不按值传递与按引用传递的问题。我认为这是一个关于for-java-each循环不按值传递与按引用传递的问题。谢谢。我意识到这是可行的。我的问题是为什么我发布的版本与您的代码不一样。谢谢。我意识到这是可行的。我的问题更多的是为什么我发布的版本与您的代码的行为不一样。显示这一点非常有用。你可能会提到你遗漏了一些不必要的细节。小提示:您使用的是另一个对象,不是第i个元素,不是对象,不是变量。感谢您的JLS参考。显示这一点非常有用。你可能会提到你遗漏了一些不必要的细节。小提示:您使用的是另一个对象,而不是第i个元素,也不是一个对象、一个变量。感谢您的JLS参考。我应该说明JVM如何处理增强的for循环;请看,这有助于解释发生了什么;看看,这有助于解释发生了什么。谢谢!现在完全清楚了,谢谢!现在完全清楚了。