Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Array seems to be getting passed by reference in Java, how is this possible? [duplicate]

I can post more code if I need to, but before that I would like to just ask a general question about the following method in which an array is passed, and then set to another array, but for some reason the original array, the one being passed in, is also getting changed, how this possible/what should i do? Thanks

tempBoard is an array of same size as currentState, and temp[k] contains the changes that are being made in movePiece, current state is declared in the method and is not a global variable

private int[][] MiniMaxBaseCase(int[][] currentState, int currentColor)
{
    tempBoard = movePiece(currentState,temp[k]);
}

private int[][] movePiece(int[][] currentState, int[] move)
{
    if(move[0] == -1)
        return currentState;

    //if the piece is just moving
    if(move[4] == -1)
    {
        currentState[move[2]][move[3]] = currentState[move[0]][move[1]];
        currentState[move[0]][move[1]] = 0;
        return currentState;
    }

    //if the piece is jumping another
    if(move[4] != -1)
    {   
        currentState[move[4]][move[5]] = currentState[move[0]][move[1]];
        currentState[move[2]][move[3]] = 0;
        currentState[move[0]][move[1]] = 0;
        return currentState;
    }

    return currentState;
}
like image 350
jbernie2 Avatar asked Feb 03 '11 23:02

jbernie2


People also ask

Do arrays get passed by reference in Java?

Arrays are Objects, yes, but nothing in Java is passed by reference. All parameter passing is by value. In the case of an Object, what gets passed is a reference to the Object (i.e. a pointer), by value. Passing a reference by value is not the same as pass by reference.

Does Java pass by reference or copy?

Java always passes arguments by value, NOT by reference.

When an array is passed to a method a reference of the array is received by the method?

When we pass an array to a method as an argument, actually the address of the array in the memory is passed (reference). Therefore, any changes to this array in the method will affect the array.

How do you reference an array in Java?

Declaring a Variable to Refer to an ArrayAn array's type is written as type[] , where type is the data type of the contained elements; the brackets are special symbols indicating that this variable holds an array. The size of the array is not part of its type (which is why the brackets are empty).


1 Answers

In Java:

  • method arguments are indeed passed-by-value, but
  • all object and array variables in Java are reference variables.

The net effect of a reference variable being passed-by-value is that the object or array pointed to by that reference variable is passed-by-reference.

Your array was effectively passed-by-reference - its the same array.

Specifically, currentState in MiniMaxBaseCase is a reference to an array - the value of it is the memory location of the array. currentState in MiniMaxBaseCase is passed by value to movePiece, so the value of currentState in MiniMaxBaseCase (a memory location) if copied into parameter currentState in movePiece - the reference was passed by value. But now currentState in movePiece points to the same memory location as currentState in MiniMaxBaseCase. So now both variables both point to the same array, i.e. the net effect was that the array was effectively passed-by-reference.


Edit: Copying multi-dimensional arrays

Some people have been suggesting to use System.arraycopy() or Array.copyOf() directly without traversing into the first dimension/index. This won't work.

Use this instead:

public static int[][] copyOf(int[][] original) {
    int[][] copy = new int[original.length][];
    for (int i = 0; i < original.length; i++) {
        copy[i] = Arrays.copyOf(original[i]);
    }
    return copy;
}

The reason a direct copy won't work is because in Java, a 2-dimensional array is really an array of pointers/references to a collection of (scattered) 1-dimensional arrays, i.e., int[][] is an array of pointers to a bunch of (scattered) int[]. Simply doing a System.arraycopy() or Arrays.copyOf() on a 2-D array will simply copy the pointers to the scattered int[] arrays, i.e. this shallow copy ends up sharing the underlying set of arrays. You must do a deep copy as shown in the code above.

Some references:

How do I do a deep copy of a 2d array in Java?

Yes, you should iterate over 2D boolean array in order to deep copy it.

http://www.cs.dartmouth.edu/~spl/Academic/Java/JFAQs.html
How do I copy multi-dimensional arrays?

... Copying a two dimensional array is however more problematical because multi-dimensional arrays are represented as arrays of arrays. This is an issue when you are cloning an array. System.arraycopy() will give you a copy of the references to the embedded arrays. ...

like image 87
Bert F Avatar answered Oct 19 '22 02:10

Bert F