3

Why is the variable changed from a method?

 2 years ago
source link: https://www.codesd.com/item/why-is-the-variable-changed-from-a-method.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

This question already has an answer here:

  • Are arrays passed by value or passed by reference in Java? [duplicate] 7 answers

Background

I am making an array tools class for adding Python functionality to a Java array, and I came across this problem. This is obviously a simplified, more universal version.

Question

In this example:

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;
    }

}

...why is changed and given the same thing?

Disclaimer

I am guessing that this has been asked before, but I couldn't find an answer, so I apologize for that.


When you do

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

given's value is called an object reference. It's a value telling the JVM where that array is, elsewhere in memory. given doesn't contain the array (like it would an int), it contains a reference to the array (e.g., like an address). E.g.:

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

When you call adjust(given), you're passing a copy of the value of given into adjust. That copy still points to the same place in memory. E.g., during the call to adjust, we have two copies of that object reference, both pointing to the same single array:

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

When you change the contents of the array, you're modifying the state of array. When adjust returns and you assign the result to changed, you have:

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

If you want a copy of the array with the changes, you'll need to make a copy of it, for instance via arraycopy. Both copying and changing-in-place are used in practice, depending on the use case.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK