Java: ¿paso por referencia o por valor? Análisis completo

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción: la batalla eterna "por referencia" vs "por valor"



Si alguna vez has programado en Java y has pasado un array u objeto a un método, y luego te has sorprendido de que los datos originales cambiaron, no estás solo. Esta pregunta atormenta a los novatos (y no solo) desde la aparición del lenguaje. En Stack Overflow ha acumulado millones de visitas, y los debates en los comentarios no cesan desde hace años.



Hoy vamos a aclarar de una vez por todas: Java, ¿es "pass-by-reference" o "pass-by-value"? Spoiler: la respuesta es inequívoca, pero el diablo, como siempre, está en los detalles. No solo daremos una definición seca, sino que mostraremos con ejemplos reales cómo funciona el paso de argumentos en Java y por qué muchos se confunden.



¿Qué dicen los creadores de Java?



La documentación oficial y el propio James Gosling (creador de Java) no dejan lugar a dudas: Java siempre pasa los argumentos por valor (pass-by-value). Sin excepciones. Ni para primitivos, ni para objetos.



Pero entonces, ¿por qué el código modifica objetos? ¿Por qué un List o un array pasado a un método se modifica? Vamos a analizarlo.



Pass-by-value: ¿qué significa exactamente?



Para empezar, una definición clara. Pass-by-value significa que al llamar a un método se crea una copia del valor de la variable, y es esa copia la que se pasa al método. La variable original (en el código que llama) permanece intacta.



Pass-by-reference es cuando al método se le pasa una referencia a la variable original, y el método puede cambiar directamente su valor (por ejemplo, reemplazar el objeto). En Java esto no existe.



Ahora, a los ejemplos.



Ejemplo 1: tipos primitivos (int, double, boolean)



Con los primitivos todo es obvio. Escribamos un código simple:



public class Main {    public static void main(String[] args) {        int x = 10;        changePrimitive(x);        System.out.println("Después del método x = " + x); // 10    }

public static void changePrimitive(int value) { value = 20; // cambiamos la copia }}


Salida:

Después del método x = 10


Todo lógico: pasamos una copia del número 10, dentro del método cambiamos la copia a 20, pero el original se quedó como estaba. Esto es pass-by-value puro.



Ejemplo 2: objetos (cadenas, listas, clases propias)



Y ahora lo más interesante. Observa:



public class Main {    public static void main(String[] args) {        StringBuilder sb = new StringBuilder("Hello");        changeStringBuilder(sb);        System.out.println("Después del método: " + sb); // Hello World!    }

public static void changeStringBuilder(StringBuilder builder) { builder.append(" World!"); // cambiamos el contenido del objeto }}


Salida:

Después del método: Hello World!


«¡Ajá! —dirás—. ¡El objeto cambió! ¡Entonces es pass-by-reference!»



No. Esta es la trampa en la que caen el 90% de los principiantes. Analicemos qué sucedió realmente.



¿Qué se almacena en la variable sb?



En Java, una variable de tipo objeto (por ejemplo, StringBuilder, List, String) no almacena el objeto en sí. Almacena una referencia (dirección) al objeto en la memoria. El objeto en sí está en algún lugar del heap.



Cuando pasas sb a un método, pasas una copia de esa referencia. Es decir, una copia de la dirección. Tanto el original como la copia apuntan al mismo objeto. Por lo tanto, cuando a través de la copia de la referencia cambias el contenido del objeto, esos cambios se ven también a través de la referencia original.



¡Pero! Si intentas asignar un nuevo objeto al parámetro dentro del método, la referencia original no cambiará. Lo demostramos:



public class Main {    public static void main(String[] args) {        StringBuilder sb = new StringBuilder("Hello");        changeReference(sb);        S                

Blogs

Book Recommendations