Parámetros por referencia en Java

09/Sep/2015 Java , 4 Comentarios

En los lenguajes de programación suelen existir dos formas de pasar los parámetros a los métodos. Parámetros por valor (dónde se realiza una copia de las variables) o parámetros por referencia (dónde se pasa una referencia a la variable original).

En Java solo ha paso de parámetros por copia. Pero entonces, por qué la gente habla del paso de parámetros por referencia en Java. Veamos en detalle por qué parece que realizamos un paso de parámetros por referencia en Java.

Paso de parámetros por valor

Lo primero que tenemos que ver es que para los datos primitivos en Java se realiza claramente una copia.

  1. public void metodo(int p) {
  2. p=3;
  3. }
  4.  
  5. int p1=2;
  6. metodo(p1);
  7.  
  8. System.out.println(p1); //p1 = 2

Paso de parámetros "por referencia": referencia de objetos

Pero ahora pasemos a manejar un objeto como parámetro. Lo que sucede al manejar los objetos en Java es que las variables mantienen una referencia al objeto, por lo tanto cuando pasamos un objeto como parámetro se está realizando una copia de la referencia. Así tenemos dos variables diferentes apuntando al mismo objeto.

Creamos una clase básica llamada MiClase:

  1. public class MiClase {
  2. public int valor;
  3. }

Y ahora un método que modifica ese valor:

  1. public static void metodo_referencia(MiClase m) {
  2. m.valor =3;
  3. }

Veamos como se pasa por valor, aunque parece que hay una referencia:

  1. MiClase m1 = new MiClase();
  2. m1.valor = 2;
  3. System.out.println(m1.valor); // Devuelve 2
  4. metodo_referencia(m1);
  5. System.out.println(m1.valor); // Devuelve 3

Hemos instanciado con un valor de 2 el atributo de la clase y el método lo cambia a 3. Como la variable copia m en el método sigue manteniendo la referencia al objeto original, se produce un cambio en dicho objeto. Por lo tanto es cuando tenemos la sensación del paso por referencia de los objetos.

Es decir, que el paso por parámetros es por valor, aunque lo que se copia es una referencia. Es por ello que tenemos la "falsa sensación" de que estamos pasando los parámetros por referencia, aunque realmente es por valor.

Desmitificando el paso de parámetros "por referencia"

Pero para verlo mejor veamos otro caso. Ahora lo que vamos a hacer es crear un nuevo objeto y cambiar la referencia de la variable pasada por copia.

  1. public static void metodo_referencia2(MiClase m1) {
  2. MiClase m2 = new MiClase();
  3. m1 = m2;
  4. m1.valor = 3;
  5. }

Lo que sucede es que ahora m1, que mantenía una referencia al objeto inicial, pasa a tener una referencia a un nuevo objeto. Por lo tanto los cambios que hagamos en m1 no afectan ya al objeto inicial.

Si volvemos a realizar la misma secuencia de salida vemos que no hay cambios en el objeto inicial.

  1. MiClase m2 = pr.new MiClase();
  2. m2.valor = 2;
  3. System.out.println(m2.valor); // Devuelve 2
  4. metodo_referencia2(m2);
  5. System.out.println(m2.valor); // Devuelve 2

Por lo tanto siempre debemos de tener en cuenta que los parámetros en Java se pasan por valor. Pero que existen las referencias a los objetos y por lo tanto podemos tener la falsa sensación de que hay paso de parámetros por referencia en Java.

Vídeos sobre Java


Difunde el Conocimiento

Si te ha gustado el artículo o te ha sido de utilidad, no dejes de compartirlo con tus amigos en las redes sociales... Te estaremos muy agradecidos. :-D

4 comentarios en “Parámetros por referencia en Java”

Víctor Cuervo

victor nahum mosso

Muy buena explicación Víctor Cuervo, con respecto a lo que comentas Ryan Quezada G. cuando estas declarando e inicializando el arrego (int [] arreglo = {1,2,3};) estas realizando lo siguiente:
int [] arreglo = new int [3];
arreglo[0] = 1;
arreglo[1] = 2
arreglo[2] = 3;

por lo tanto al pasarlo como parámetro al método “modificarArreglo(arreglo)” estas pasando una variable copia de int [] arreglo la cual apunta a la misma dirección de memoria entonces la explicación inicial es correcta el paso es por valor no por referencia.

public class TestMain {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
try {
new TestMain().exampleTeoryObject();
} catch (Exception e) {
e.printStackTrace();
}

}
public void exampleTeoryObject(){
int[] nums = {1,2,3};
System.out.println(“El valor de la cadena antes de ser enviado como parametro al mentodo example() nums[].- ” + nums[0]+” “+nums[1]+” “+nums[2]);
example(nums);
System.out.println(“El valor de la cadena despues de ser enviado como parametro al mentodo example() nums[].- ” + nums[0]+” “+nums[1]+” “+nums[2]);
}

public void example(int[] nums){
int[] arr2 = new int[3];
arr2[0] = nums[0];
arr2[1] = nums[1];
arr2[2] = nums[2];
nums = arr2;
for(int i = 0;i<nums.length;i++){
nums[i] = nums[i]*3;
}
System.out.println("El valor de la cadena dentro del mentodo example() nums[].- " + nums[0]+" "+nums[1]+" "+nums[2]);
}
}

Víctor Cuervo

Ryan Quezada G.

en java existe el paso por referencia. Lo que pasa es que no sucede con valores primitivos ni con los objetos inmutables. Como sucede con los strings.

un ejemplo puede ser de objeto Inmutable:
sysout significa “System.out.println”, es la plantilla de codigo de salida por consola de eclipse.
String cadena = “hola”;
cadena.reemplazar();
sysout(cadena);

public void reemplazar(){
cadena=”bye”;
}

Que crees que pasa aqui? No pasa nada, porque el string es inmutable, no se puede modificar. En caso de que pasemos un arreglo el efecto seria

int [] arreglo = {1,2,3};

modificarArreglo(arreglo);

for (int i = 0; i < arreglo.length; i++) {
sysout(arreglo[i]);
}

public void modificar arreglo(int[] array){

for (int i = 0; i < array.length; i++) {
//se modifican aqui los elementos del arreglo por 3.
array[i]*=3;
}
}

el resultado seria: (3, 6, 9).

El paso por referencia significa "enviar a un metodo cualquiera la direccion de memoria de el objeto al metodo". Lo cual al operacionalizar en el mismo, cambia, porque no se envia una copia del valor, sino la direccion del objeto.

Es mucho mas rapido que el paso por valor… Pero no es tan facil mantener los datos originales.

Víctor Cuervo

Unto canari Cs

Muy buenos ejemplos.
Me he dado cuenta de que se ha colado una “p” en un sitio. Busca (Ctrl+F) en esta misma pagina(http://lineadecodigo.com/java/parametros-por-referencia-en-java/) “pnew” y lo veras.
Un saludo

Víctor Cuervo

Víctor Cuervo

Gracias por detectar la errata. Solucionado.

¿Algo que nos quieras comentar?

Déjanos tu comentario, no te preocupes que tu email no será publicado

*

*