Java es pasa por valor, no pasa por referencia

Introducción

Muchos programadores de Java se preguntan si Java es pasado por valor o pasado por referencia. Este artículo resume por qué Java siempre se pasa por valor.

Primero, ¿qué significa pasar por valor y pasar por referencia?

  • Pasar por valor: Los valores de los parámetros del método se copian en otra variable y luego se pasa el objeto copiado al método. El método utiliza la copia.
  • Pasar por referencia: Se pasa un alias o referencia al parámetro real al método. El método accede al parámetro real.

A menudo, la confusión en torno a estos términos es resultado del concepto de la referencia de objeto en Java. Técnicamente, Java siempre se pasa por valor, porque aunque una variable pueda contener una referencia a un objeto, esa referencia de objeto es un valor que representa la ubicación del objeto en la memoria. Por lo tanto, las referencias de objetos se pasan por valor.

Tanto los tipos de datos de referencia como los tipos de datos primitivos se pasan por valor. Aprende más sobre los tipos de datos en Java.

Además de comprender los tipos de datos, también es importante entender la asignación de memoria en Java, porque los tipos de datos de referencia y los tipos de datos primitivos se almacenan de manera diferente.

Demonstrando el pase por valor

El siguiente ejemplo demuestra cómo se pasan los valores en Java.

El programa de ejemplo utiliza la siguiente clase:

public class Balloon {

	private String color;

	public Balloon() {}
	
	public Balloon(String c) {
		this.color = c;
	}
	
	public String getColor() {
		return color;
	}

	public void setColor(String color) {
		this.color = color;
	}
}

El siguiente programa de ejemplo utiliza un método genérico, swap(), que intercambia dos variables. Otro método, changeValue(), intenta cambiar los valores de las variables.

public class Test {

	public static void main(String[] args) {

		Balloon red = new Balloon("Red"); // referencia de memoria = 50
		Balloon blue = new Balloon("Blue"); // referencia de memoria = 100
		
		swap(red, blue);
		System.out.println("After the swap method executes:");
		System.out.println("`red` color value = " + red.getColor());
		System.out.println("`blue` color value = " + blue.getColor());
		
		changeValue(blue);
		System.out.println("After the changeValue method executes:");
		System.out.println("`blue` color value = " + blue.getColor());
		
	}

	// Método de intercambio genérico
	public static void swap(Object o1, Object o2){
		Object temp = o1;
		o1 = o2;
		o2 = temp;
	}

	private static void changeValue(Balloon balloon) { // globo = 100
		balloon.setColor("Red"); // globo = 100
		balloon = new Balloon("Green"); // globo = 200
		balloon.setColor("Blue"); // globo = 200
	}

}

Cuando ejecutas el programa de ejemplo, obtienes la siguiente salida:

Output
After the swap method executes: 'red' color value = Red 'blue' color value = Blue After the changeValue method executes: 'blue' color value = Red

La salida muestra que el método swap() no intercambió los valores de color de los objetos originales. Esto ayuda a demostrar que Java pasa por valor, ya que el método swap() solo actúa sobre copias de los valores de referencia originales del objeto.

Esta prueba del método swap() se puede usar con cualquier lenguaje de programación para verificar si es de paso por valor o por referencia.

El Ejemplo Método swap() Explicado

Cuando usas el operador new para crear una instancia de una clase, se crea el objeto y la variable contiene la ubicación en la memoria donde se guarda el objeto.

Balloon red = new Balloon("Red");
Balloon blue = new Balloon("Blue");

Aquí hay un desglose paso a paso de lo que sucede cuando se ejecuta el método swap():

  • Supongamos que red apunta a la ubicación de memoria 50 y blue apunta a la ubicación de memoria 100, y que estas son las ubicaciones de memoria de ambos objetos Balloon.

  • Cuando la clase llama al método swap() con las variables red y blue como argumentos, se crean dos nuevas variables de objeto, o1 y o2. o1 y o2 también apuntan a las ubicaciones de memoria 50 y 100, respectivamente.

  • El siguiente fragmento de código explica lo que sucede dentro del método swap():

    public static void swap(Object o1, Object o2) { // o1 = 50, o2 = 100
    	Object temp = o1; // asigna el valor de referencia del objeto o1 a temp: temp = 50, o1 = 50, o2 = 100
    	o1 = o2; // asigna el valor de referencia del objeto o2 a o1: temp = 50, o1 = 100, o2 = 100
    	o2 = temp; // asigna el valor de referencia de temp a o2: temp = 50, o1 = 100, o2 = 50
    } // método terminado
    
  • Los valores de o1 y o2 se intercambian, pero como los valores son copias de las ubicaciones de memoria red y blue, no hay cambio en los valores de las colores red y blue.

Dado que las variables contienen la referencia a los objetos, es un error común asumir que estás pasando la referencia y que Java pasa por referencia. Sin embargo, estás pasando un valor que es una copia de la referencia y, por lo tanto, se pasa por valor.

El método de ejemplo changeValue() explicado

El siguiente método en el programa de ejemplo cambia el valor del color del objeto al que hace referencia la variable blue:

private static void changeValue(Balloon balloon) { // globo = 100
	balloon.setColor("Red"); // globo = 100
	balloon = new Balloon("Green"); // globo = 200
	balloon.setColor("Blue"); // globo = 200
}

Aquí tienes un desglose paso a paso de lo que sucede dentro del método changeValue():

  • La clase llama al método changeValue() en la variable blue que referencia la ubicación de memoria 100. La primera línea crea una referencia que también apunta a la ubicación de memoria 100. El valor de color del objeto en la ubicación de memoria 100 se cambia a "Rojo".

  • La segunda línea crea un nuevo objeto (con valor de color "Verde"). El nuevo objeto está en la ubicación de memoria 200. Cualquier otro método ejecutado en la variable balloon actúa sobre el objeto en la ubicación de memoria 200 y no afecta al objeto en la ubicación de memoria 100. La nueva variable balloon sobrescribe la referencia creada en la línea 1 y la referencia de balloon de la línea 1 ya no es accesible dentro de este método.

  • La tercera línea cambia el valor de color del nuevo objeto Balloon en la ubicación de memoria 200 a "Blue", pero no afecta al objeto original referenciado por blue en la ubicación de memoria 100. Esto explica por qué la última línea de la salida del programa de ejemplo imprime blue color value = Red, lo que refleja el cambio desde la línea 1.

Conclusión

En este artículo aprendiste por qué Java pasa por valor. Continúa tu aprendizaje con más tutoriales de Java.

Source:
https://www.digitalocean.com/community/tutorials/java-is-pass-by-value-and-not-pass-by-reference