Brett Penza
Brett Penza

Reputation: 39

Java Two Dimensional Array passed to method and not changed

This question about a 2D array being passed into a method came up in class. Can someone explain why the original array d is unchanged after a call to doStuff() ? I debugged the code and saw that the method was reversing the values, but then when returned, the original array remained unchanged. I thought passing arrays into a method and changing values in that method would affect the original array. Here that is not the case, the original array is unchanged. My first thought was the orignal would be reversed. But no.

  1. Initialize the array d and call doStuff as follows:

        int d[][] = { {-1,0,1},  
                      {5,6,7},  
                      {2,3,4} };  
        doStuff(d);    
    
    
        public static void doStuff (int [][] frst)    
        {    
            int len = frst.length;    
            int sec[][] = new int[len] [];    
            for (int j=0; j<len; j++)  
            {        
                sec[j] = frst[len –j -1];     
            }       
            frst = sec;      
        }    
    

Upvotes: 2

Views: 1957

Answers (3)

jas
jas

Reputation: 10865

You already have some good answers, but here's a bit of code showing the two cases that may seem to be inconsistent, but are indeed explained by the fact that java is pass-by-value. The tricky bit is that in the case of arrays, it's the reference to the array that's being passed by value, not the array itself.

Hence the called function receives a copy of the reference to the same array as the caller function, and can modify elements within that array. But when the called function modifies the reference itself to refer to a different array it is modifying a copy, which has no effect on the caller --- that is, in the caller environment the variable is still referring to the original array.

This is easier to explain with boxes and arrows :-), but hopefully the code and output below will be helpful:

$ cat PBV.java
class PBV
{
    private static void modfiyArrayElement(int[] intArray) {
        // intArray is referring to the same array as in main
        intArray[0] = 17;
    }

    public static void main(String[] args) {
        int[] a = new int[]{ 1, 2, 3 };
        System.out.println(a[0]);

        modifyArrayElement(a);
        System.out.println(a[0]);
    }
}

$ java PBV
1
17

$ cat PBV2.java
class PBV2
{
    private static void modfiyArrayReference(int[] intArray) {
        System.out.println("\nIn modifyArrayReference:");
        System.out.println("intArray[0] is " + intArray[0]);
        System.out.println("ref value of intArray is: " + intArray);

        intArray = new int[] { 100, 200, 300 };            

        // intArray is no longer referring to the same array as in main!
        // at this point munging with intArray won't have an effect in main

        System.out.println("\nintArray[0] is now " + intArray[0]);
        System.out.println("ref value of intArray is: " + intArray +"\n");
    }

    public static void main(String[] args) {
        System.out.println("in main:");
        int[] a = new int[]{ 1, 2, 3 };
        System.out.println("a[0] is " + a[0]);
        System.out.println("ref value of a is: " + a);

        modfiyArrayReference(a);

        System.out.println("back in main:");
        System.out.println("a[0] is still " + a[0]);
        System.out.println("ref value of a is still: " + a);
    }
}

$ java PBV2
in main:
a[0] is 1
ref value of a is: [I@55a6c368

In modifyArrayReference:
intArray[0] is 1
ref value of intArray is: [I@55a6c368

intArray[0] is now 100
ref value of intArray is: [I@37670cc6

back in main:
a[0] is still 1
ref value of a is still: [I@55a6c368

Upvotes: 1

micklesh
micklesh

Reputation: 417

Here what happens. There are 2 arrays created, the initial one and the second, created inside the doStuff method.

There are 3 references (variables) to the arrays in the code:

  • external (for the method): d

  • internal: first and sec.

Inside the doStuff method the second array is indeed populated as the reverse of the initial which is not changed at all.

At the end of the doStuff method both first and sec reference the same object, the second one, and not the original - hence the behavior you see

Upvotes: 0

Secret
Secret

Reputation: 3358

Java is pass by value

Return your value and set it to your value.

        int d[][] = { {-1,0,1},
                      {5,6,7},
                      {2,3,4} };
        d = doStuff(d);


        public static int[][] doStuff (int [][] frst)
        {
            int len = frst.length;
            int sec[][] = new int[len] [];
            for(int j=0; j<len; j++)
                sec[j] = frst[len-j-1];
            return sec;
        }

}

You can also set the value of the passed array directly (array variables are a reference to an array, so editing the elements of your passed array reference will work:

public static void doStuff (int [][] frst)
            {
                int len = frst.length;
                int sec[][] = new int[len] [];
                for(int j=0; j<len; j++)
                    sec[j] = frst[len-j-1];
                for(int j=0; j<frst.length;j++)
                    frst[j] = sec[j]
            }

Upvotes: 0

Related Questions