Rareza en matrices Java comparadas: referencias frente a punteros

Tiene un problema para entender lo que está pasando en el siguiente código. El comportamiento de las matrices.c yd Es lo que yo esperaría. Pero que pasa cona yb? (También probé esto con variables normales, escalares, y no sucede nada sorprendente en ninguno de los casos).

La salida se copia a los comentarios RH.

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]
    }
}

La intercambiabilidad dec yd indica paso por valor de acuerdo a este post:Java es pasar por valor, maldita sea!. (También miré¿La matriz java pasa por referencia no funciona?, pero no puedo entender el inglés del autor de la pregunta, y la llamada al método oscurece el ejemplo.)

Note que con la línead = tmp; Comentado,c yd exhiben el mismo comportamiento extraño quea yb. Todavía no sé qué hacer con eso.

¿Alguien puede explicar cómoa yb¿Se puede explicar el comportamiento con paso por valor?

Editar: Addendum

Resulta que el problema principal en mi publicación no es el paso por valor, sino el aliasing. Para dejar en claro la distinción entre paso por valor y punteros, agregué el siguiente método a mi código y lo usé para (intentar) intercambiarc yd (sugerido por unartículo enlazado por el artículo de JavaDude enlazado arriba).

static <T> void swap (T c, T d) {
    T tmp = c;
    c = d;
    d = tmp;
}

El resultado es quec yd volver sin cambios Esto hubiera funcionado si Java (como C) pasara los punteros ac yd al método, pero en su lugar simplemente pasa sus valores, dejando las variables originales sin cambios.

Cambiandoa = b aa = b.clone(); o paraa = Arrays.copyOf(b, b.length); Da el comportamiento que estaba esperando. Este código también funciona:

    int[] tmp = new int[b.length];
    System.arraycopy( b, 0, tmp, 0, b.length );
    a = tmp;

Momento relativo descritoaquí.

Respuestas a la pregunta(4)

Su respuesta a la pregunta