java foreach循环中的数组引用

java 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

我试图使用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循环的行为与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循环;请看,这有助于解释发生了什么;看看,这有助于解释发生了什么。谢谢!现在完全清楚了,谢谢!现在完全清楚了。