HOWTO · Java

Array pasado por valor o por referencia en Java

Este artículo presenta la verificación si el array se pasa por valor o se pasa por referencia en Java.

En esta página

Java pasa todos los argumentos de método por valor. Cuando el argumento es un array, el valor que se copia en el parámetro es una referencia al objeto array. Por tanto, quien llama y el parámetro pueden referirse al mismo objeto, aunque siguen siendo variables distintas. Esto explica por qué quien llama ve el cambio de un elemento, pero no la asignación de otro array al parámetro.

Cómo Java pasa los argumentos

Una referencia es un valor que permite acceder a un objeto; no es el objeto en sí. Un método recibe una copia de ese valor de referencia. Al comenzar la llamada, la variable array de quien llama y el parámetro del método se refieren al mismo objeto array. Java no pasa por referencia la propia variable array, así que el método no puede reemplazar la variable de quien llama asignando otro valor a su propio parámetro.

La diferencia está entre modificar un objeto y cambiar una variable. Asignar un valor a un elemento del array modifica el objeto compartido. Asignar un valor al parámetro cambia únicamente la referencia copiada de ese parámetro. Estas operaciones tienen efectos distintos, aunque ambas se realicen dentro del método llamado.

Cómo afectan a quien llama los cambios en los elementos del array

Cuando un método escribe en values[index], modifica un elemento del objeto array al que pueden acceder ambas referencias. Quien llama ve ese cambio cuando termina el método. La referencia se pasó por valor; la modificación del elemento es visible porque la referencia copiada sigue permitiendo acceder al mismo objeto.

Qué ocurre cuando un método reasigna un parámetro array

Asignar un array nuevo al parámetro hace que este se refiera a otro objeto. No cambia la variable de quien llama, que sigue refiriéndose al array original. Quien llama puede ver las modificaciones hechas al objeto original antes de la reasignación, pero no recibe la nueva referencia del parámetro. Para reemplazar la variable array de quien llama, devuelve el array nuevo y asigna el valor devuelto en el lugar de la llamada, o modifica el array original.

Cómo se comportan los parámetros primitivos

Los argumentos primitivos también se pasan por valor: el parámetro empieza con una copia del valor primitivo. Si un método asigna otro número a ese parámetro, la variable de quien llama no cambia. Esto se parece a reasignar un parámetro array, no a modificar un elemento del array. En el caso del array hay una referencia: el valor copiado permite modificar el objeto compartido, mientras que asignar una referencia nueva solo afecta al parámetro local.

Ejecuta este ejemplo autónomo:

El código y las etiquetas o salidas visibles de esta sección se mantienen en inglés.

public class ArrayArgumentDemo {
    static void changeFirst(int[] values) {
        values[0] = 9;
    }

    static void replaceParameter(int[] values) {
        values = new int[] {7, 8};
    }

    static void changeNumber(int number) {
        number = 9;
    }

    public static void main(String[] args) {
        int[] numbers = {1, 2};
        changeFirst(numbers);
        System.out.println(numbers[0]);
        replaceParameter(numbers);
        System.out.println(numbers[0]);

        int count = 1;
        changeNumber(count);
        System.out.println(count);
    }
}
9
9
1

La primera impresión muestra el elemento modificado. La segunda muestra que el array de quien llama sigue sin cambios después de asignar otro array al parámetro del método. La última impresión muestra que la variable primitiva de quien llama tampoco cambia.

Idea clave

Java siempre pasa los argumentos por valor, incluidas las referencias a arrays. La modificación de un elemento es visible cuando quien llama y el parámetro del método se refieren al mismo objeto array. Reasignar el parámetro solo cambia su referencia local, y asignar un valor a un parámetro primitivo solo cambia su copia local. Distinguir la modificación del objeto de la asignación al parámetro permite prever el comportamiento.