为什么变量是从方法中修改的?

时间:2016-10-12 16:52:45

标签: java arrays methods scope

背景

我正在创建一个用于向Java数组添加Python功能的数组工具类,我遇到了这个问题。这显然是一个简化的,更通用的版本。

问题

在这个例子中:

public class ArrayTest
{

    public static void main(String[] args)
    {
        // initial setup
        int[] given = {1, 2, 3, 4, 5};

        // change array
        int[] changed = adjust(given);

        // these end up being the same...
        System.out.println(Arrays.toString(changed));
        System.out.println(Arrays.toString(given));
    }
    private static int[] adjust(int[] a)
    {
        for (int i = 0; i < a.length; i++)
        {
            a[i]++;
        }
        return a;
    }

}

...为什么changedgiven同样如此?

声明

我猜这个问题之前已被问过,但我找不到答案,所以我为此道歉。

2 个答案:

答案 0 :(得分:3)

当你这样做时

int[] given = {1, 2, 3, 4, 5};

given的值称为对象引用。它是一个值告诉JVM该数组在哪里,在内存中的其他位置。 given 不包含数组(就像int一样),它包含数组的引用(例如,像地址一样) )。 E.g:

                     +−−−−−−−−−+
[given:Ref88465]−−−−>| (array) |
                     +−−−−−−−−−+
                     | 0: 1    |
                     | 1: 2    |
                     | 2: 3    |
                     | 3: 4    |
                     | 4: 5    |
                     +−−−−−−−−−+

当您致电adjust(given)时,您将given的值副本传递给adjust。该副本仍然指向内存中的相同位置。例如,在调用adjust期间,我们有两个该对象引用的副本,两者都指向同一个数组:

                     +−−−−−−−−−+
[given:Ref88465]−−−−>| (array) |
                  /  +−−−−−−−−−+
                  |  | 0: 1    |
                  |  | 1: 2    |
                  |  | 2: 3    |
                  |  | 3: 4    |
                  |  | 4: 5    |
                  |  +−−−−−−−−−+
[a:Ref88465]−−−−−−+

当您更改数组的内容时,您正在修改数组的状态。当adjust返回并将结果分配给changed时,您有:

                      +−−−−−−−−−+
[given:Ref88465]−−−−−>| (array) |
                   /  +−−−−−−−−−+
                   |  | 0: 2    |
                   |  | 1: 3    |
                   |  | 2: 4    |
                   |  | 3: 5    |
                   |  | 4: 6    |
                   |  +−−−−−−−−−+
[changed:Ref88465]−+

如果您想要更改数组的副本,则需要复制它,例如通过arraycopy。复制和就地更改都在实践中使用,具体取决于用例。

答案 1 :(得分:0)

你正在做的是将你的数组的地址发送到你的方法,所以更改的是你的原始数组,你只需返回它(你的数组的地址)所以你对该数组所做的任何更改(内存)将反映在两个变量中,因为两者都指向相同的内存位置