Reputation: 169
I know that Java is always pass-by-value, but I do not understand why this works:
public static void swap(int[] arr, int i, int j)
{
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
public static void main(String[] args)
{
int[] arr = {3, 4, 5, 6};
swap(arr, 1, 3);
// arr becomes {3, 6, 5, 4}
}
And this does not work:
public static void swap(int[] arr, int[] arr2)
{
int[] tmp = arr;
arr = arr2;
arr2 = tmp;
}
public static void main(String[] args)
{
int[] arr = {3, 4, 5, 6};
int[] arr2 = {1, 2, 5, 6};
swap(arr, arr2);
}
Why?
Upvotes: 12
Views: 1150
Reputation: 63991
In the second method, you are trying to swap references, which will not work because the references themselves are pass-by-value.
The first method works correctly because it changes the object referenced by the array (which is mutable), it does not change the reference itself.
Check out this blog post for more details on the differences between pass-by-value and pass-by-reference.
Upvotes: 14
Reputation: 1335
The first swap you change the data of the array. (referenced by arr : a reference) so it is modified
The second swap, you change arr, arr2, two local variables. so when you quit the method, the two new variable are destroyed
Upvotes: 1
Reputation: 59
Upvotes: 1
Reputation: 81539
If you've ever used C or C++ and know about how pointers work, then what made this whole scenario tick for me is the following statement:
In Java, everything is passed by value.
In case of Objects, the reference (pointer) is passed by value.
So basically the swap function of
public void swap(int[] a, int[] b)
{
etc.
}
Will just get the pointer to the a
int[] array, and the pointer to the b
int[] array.
You're just swapping two pointers. You cannot modify the content of pointers like that.
Basically the C equivalent is
void swap(int* a, int* b)
{
int* temp = a;
a = b;
b = temp;
}
int main(void)
{
int a[] = {5,6,7,8};
int b[] = {1,2,3,4};
swap(a,b);
}
While even in C, this would only work like so:
void swap(int** a, int** b)
{
int* temp = (*a);
(*a) = (*b);
(*b) = temp;
}
int main(void)
{
int a[] = {5,6,7,8};
int b[] = {1,2,3,4};
swap(&a, &b);
}
Of course, you can't send the reference of a reference in Java. Pointers in this sense don't exist in Java.
Therefore, in order to actually modify the object in another function, you would need a "Holder" object to which the reference is copied, but the reference inside it to the object you want to modify IS actually the actual reference of the object, if that made sense.
And thus, the following would work:
public class ArrayHolder
{
public int[] array;
public ArrayHolder(int[] array)
{
this.array = array;
}
}
public void swap(ArrayHolder a, ArrayHolder b)
{
int[] temp = a.array;
a.array = b.array;
b.array = temp;
}
public static void main(String[] args)
{
ArrayHolder aaa = new ArrayHolder(new int[] {5,6,7,8});
ArrayHolder bbb = new ArrayHolder(new int[] {1,2,3,4});
swap(aaa,bbb);
}
Upvotes: 3
Reputation: 24630
Your first example is transfering the values in the array.
The second you are trying to interchange the reference (arrays are objects in Java). The references are local copies (pass-by-value) and has not effect on the calee context.
(Question #56.903 about call-by-value; Stackexchange should open PassByValue.com ;-)
Upvotes: 7