-2

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.

JakeD
  • 2,788
  • 2
  • 20
  • 29
  • 1
    You're right that this must be a duplicate. Searching for it is tricky, but we should be able to find one. – T.J. Crowder Oct 12 '16 at 16:57
  • 2
    modifying the array passed into a method will modify that array: http://stackoverflow.com/questions/12757841/are-arrays-passed-by-value-or-passed-by-reference-in-java – scrappedcola Oct 12 '16 at 16:57

2 Answers2

3

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.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
0

what you are doing is sending the address of your array to your method , so what was changed is your original array and you just return it( the address of your array) so any change you have done on that array(memory) will be reflected in both variables as both are pointing to the same memory location

Amer Qarabsa
  • 6,412
  • 3
  • 20
  • 43
  • 2
    In Java we are not talking about _address_ but about _reference_. – Seelenvirtuose Oct 12 '16 at 17:01
  • Not really , references are misunderstood, they are more like pointers actually – Amer Qarabsa Oct 12 '16 at 17:02
  • And what i meant(sorry if that was not clear) is just address more like a proxy not a physical address of the memory – Amer Qarabsa Oct 12 '16 at 17:03
  • 1
    Oh oh. No! It is _reference_! Please stick to the correct terms. – Seelenvirtuose Oct 12 '16 at 17:03
  • 2
    @AmerQarabsa reference variables hold values which allow JVM map that value to proper object location. Objects can be moved inside memory by JMV so their address may change, but that doesn't mean reference will also change. – Pshemo Oct 12 '16 at 17:03
  • you are not sending the reference – Amer Qarabsa Oct 12 '16 at 17:04
  • 1
    You are sending the copy of a reference. Pointers can change the address they point to, which in Java is prohibited. – MaxZoom Oct 12 '16 at 17:04
  • @Pshemo ,@MaxZoom I agree with both of you , this copy of the reference is basically the address to that reserved memory in the heap , not the physical memory i mean a proxy to that location , about using "copy of reference" i do not see thats accurate maybe better to say "value of reference" ? – Amer Qarabsa Oct 12 '16 at 17:08
  • 1
    @AmerQarabsa: It's a copy of the value, just like `int a = 42; int b = a;` copies the value of `a` (42) into `b`. The value in that case is an `int`; in the OP's case it's an object reference, but it's a value either way. So "copy of the reference" is entirely correct. – T.J. Crowder Oct 12 '16 at 17:24
  • Well guess thats correct. – Amer Qarabsa Oct 12 '16 at 17:29