java foreach循环中的数组引用

Bri*_*anS 1 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());
    }
    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());
    }
}
Run Code Online (Sandbox Code Playgroud)

但是在for循环退出后,数组元素为null.这是输出:

inside for loop 1
why isn't this 1?  null
Not it's okay: 2
Run Code Online (Sandbox Code Playgroud)

为什么这个for循环的行为不一样for (i=0;i<1;i++){x[i]=1;}

T.J*_*der 5

出于完全相同的原因,这不起作用:

Integer a1 = null;
Integer a2 = a1;
a2 = new Integer(1);
System.out.println(a1.toString()); // Fails, a1 is still null
Run Code Online (Sandbox Code Playgroud)

xx在你的循环是不是某种参考数组元素; 相反,它是一个包含数组元素值的副本的变量(null在您的情况下).设置xxjust 的值只是设置它的值,它对数组条目没有任何影响.

让我们按照您的代码:

Integer[] x = new Integer[1];
Run Code Online (Sandbox Code Playgroud)

在内存中,我们现在有这样的东西(忽略一些细节):

                 +???????????+
x[Ref22135]?????>| Integer[] |
                 +???????????+
                 | length: 1 |
                 | 0: null   |
                 +???????????+

(里面的"Ref22135" x是一个称为对象引用的值,告诉JVM数组在内存中的位置.对象引用是值,就像基元一样.我们处理对象的事实实际上与设置xx不相关的事实无关影响x[0],但既然你正在使用Integer[],我必须提到它.)

现在,我们进入你的循环:

for (Integer xx : x) {
Run Code Online (Sandbox Code Playgroud)

此时,再次忽略一些细节,我们有:

                 +???????????+
x[Ref22135]?????>| Integer[] |
                 +???????????+
                 | length: 1 |
                 | 0: null   |
                 +???????????+

xx[null]

x[0](null)的值已复制xx.

现在我们完成你的任务:

    xx = new Integer(1);
Run Code Online (Sandbox Code Playgroud)

这给了我们:

                 +???????????+
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]);
Run Code Online (Sandbox Code Playgroud)

输出:

42
0

如果我们此时停止该代码:

int[] array = new int[1];
for (int entry : array)
{
    entry = 42;
Run Code Online (Sandbox Code Playgroud)

我们在记忆中看到的东西如下:

                     +???????????+
array[Ref56418]?????>| int[]     |
                     +???????????+
                     | length: 1 |
                     | 0: 0      |
                     +???????????+

entry[42]

当我们使用唯一的区别Integer[]是,从正被复制的值x[0]xx是一个对象引用,而不是int.但没关系; 它仍然是一个值,当从一个事物分配给另一个事物时,值总是被复制.(复制对象引用只是复制引用,当然不是它引用的对象).