Having a problem understanding what's going on n the code below. The behavior of arrays c
and d
is what I would expect. But what's going on with a
and b
? (I also tried this with normal, scalar variables, and nothing surprising happens in either case.)
The output is copied to the RH comments.
import java.util.Arrays;
public class ArraysParadox {
public static void main(String[] args) {
int[] c = {1, 2, 3};
int[] d = {6, 5, 4, 3};
System.out.print("c: ");
System.out.println(Arrays.toString(c)); // c: [1, 2, 3]
System.out.print("d: ");
System.out.println(Arrays.toString(d)); // d: [6, 5, 4, 3]
System.out.println("--- swap ---");
int[] tmp = c;
c = d;
d = tmp; // <----- Magic?
System.out.print("c' (=d): ");
System.out.println(Arrays.toString(c)); // c' (=d): [6, 5, 4, 3]
System.out.print("d' (=c): ");
System.out.println(Arrays.toString(d)); // d' (=c): [1, 2, 3]
System.out.println("--- c = 0 ---");
Arrays.fill(c, 0);
System.out.print("c (=0): ");
System.out.println(Arrays.toString(c)); // c (=0): [0, 0, 0, 0]
System.out.print("d (=c): ");
System.out.println(Arrays.toString(d)); // d (=c): [1, 2, 3]
System.out.println("--- d = 1 ---");
Arrays.fill(d, 1);
System.out.print("c (=d): ");
System.out.println(Arrays.toString(c)); // c (=d): [0, 0, 0, 0]
System.out.print("d (=1): ");
System.out.println(Arrays.toString(d)); // d (=1): [1, 1, 1]
System.out.println("================");
int[] a = {1, 2, 3};
int[] b = {6, 5, 4, 3};
System.out.print("a: ");
System.out.println(Arrays.toString(a)); // a: [1, 2, 3]
System.out.print("b: ");
System.out.println(Arrays.toString(b)); // b: [6, 5, 4, 3]
a = b;
System.out.print("a (=b): ");
System.out.println(Arrays.toString(a)); // a (=b): [6, 5, 4, 3]
System.out.println("--- α = 0 ---");
Arrays.fill(a, 0);
System.out.print("a (=0): ");
System.out.println(Arrays.toString(a)); // a (=0): [0, 0, 0, 0]
System.out.print("b (=a?): ");
System.out.println(Arrays.toString(b)); // b (=a?): [0, 0, 0, 0] ???
System.out.println("--- b = 1 ---");
Arrays.fill(b, 1);
System.out.print("b (=1): ");
System.out.println(Arrays.toString(b)); // b (=1): [1, 1, 1, 1]
System.out.print("a (=b?): ");
System.out.println(Arrays.toString(a)); // a (=b?): [1, 1, 1, 1]
}
}
The swapability of c
and d
indicates pass-by-value according to this post: Java is Pass-by-Value, Dammit!. (I also looked at java array pass by reference does not work?, but I can't understand the asker's English, and the method call obscures the example.)
Notice that with the line d = tmp;
commented out, c
and d
exhibit the same odd behavior as a
and b
. Still I don't know what to make of it.
Can anyone explain how a
and b
's behavior can be explained with pass-by-value?
Edit: Addendum
It turns out the main issue in my post is not pass-by-value, but aliasing. To be clear about the distinction between pass-by-value and pointers, I added the following method to my code and used it to (try to) swap c
and d
(suggested by an article linked by JavaDude's article linked above).
static <T> void swap (T c, T d) {
T tmp = c;
c = d;
d = tmp;
}
The result is that c
and d
come back unchanged. This would have worked if Java (like C) passed along pointers to c
and d
to the method, but instead it simply passes their values, leaving the original variables unchanged.
Changing a = b
to a = b.clone();
or to a = Arrays.copyOf(b, b.length);
gives the behavior I was expecting. This code also works:
int[] tmp = new int[b.length];
System.arraycopy( b, 0, tmp, 0, b.length );
a = tmp;
Relative timing descried here.