Paso de variables por Valor y por Referencia en Java
En el paso de parámetros de variables a métodos en Java se suele decir que:
- las variables de tipo simple (int, double, etc) se pasan por valor
- los objetos se pasan por referencia.
Ésto no es cierto, después de consultar varias fuentes puedo concluir que en Java las variables, ya sean simples u objetos, se pasan siempre por valor.
El hecho de hacernos pensar que los objetos se pasan por referencia se debe a que si pasamos un objeto a un método y modificamos su valor dentro del método, al salir de éste, nuestro objeto habrá sido modificado.
Pero nosotros en realidad no hemos pasado el objeto como tal, sino que hemos pasado por valor la referencia al objeto, es decir, le hemos pasado una copia de su dirección en memoria.
Por lo tanto, cuando pasamos un objeto a un metodo, siempre estaremos pasando una copia de su dirección, por lo que aunque le cambiemos la direccion, en cuanto salga del metodo, volverá a tener la dirección original. Sin embargo, si dentro del método accedemos a su contenido y lo modificamos, éste si que seguirá modificado una vez salgamos del método, porque el contenido no es ninguna copia.
Para que se entienda mejor, podéis probar ésto:
import java.awt.Point;
class PassByValue
{
public static void modifyPoint(Point pt, int j)
{
pt.setLocation(5,5); //1
j = 15;
System.out.println("During modifyPoint " + "pt = " + pt +
" and j = " + j);
}
public static void main(String args[])
{
Point p = new Point(0,0); //2
int i = 10;
System.out.println("Before modifyPoint " + "p = " + p +
" and i = " + i);
modifyPoint(p, i); //3
System.out.println("After modifyPoint " + "p = " + p +
" and i = " + i);
}
}
Que dará de salida esto:
Before modifyPoint p = java.awt.Point[x=0,y=0] and i = 10
During modifyPoint pt = java.awt.Point[x=5,y=5] and j = 15
After modifyPoint p = java.awt.Point[x=5,y=5] and i = 10

13 Comentarios
KURAGARi
Y si lo que quieres es poder cambiar el contenido de un tipo básico como el bolean, el int o el String dentro de un método (lo que en C# se hace añadiendo un “ref” que preceda la declaración del parámetro o el & de C/C++) como lo harías?
23 de febrero, 2009 a las 2:38 pmJose Dueñas
@KURAGARi: de una forma directa como en C no se puede ya que como dijimos Java siempre pasa por valor los tipos básicos.
Una posible solución pasaría por “camuflar” ese tipo básico en un objeto.
Por ejemplo, pasariamos como argumento un array que contendria solamente a éste tipo básico para poder modificarlo sin problema.
Veámoslo con ujemeplo en el que cambiamos una variable de tipo int:
public static void modificarVariable(int [] array)
{
array[0] = 99; //mi nuevo valor sera 99
}
public static void main(String args[])
{
int[] miVariable = { 1 };
modificarVariable(miVariable);
System.out.println("El nuevo valor de mi variable es: " + miVariable[0]);
}
De todos modos es poco elegante y se debería evitar ésta práctica.
Un saludo
23 de febrero, 2009 a las 10:17 pmMariano
Lo que dice KURAGARi no es posible debido a que Java, a diferencia de C*, no permite trabajar con punteros. Para hacer lo que tu dices es necesario poder manejar punteros a memoria
10 de marzo, 2009 a las 4:06 amFranco
Mas elegante seria instanciar una clase wrapper de integer, por ejemplo: Integer nro = new Integer(3);
22 de abril, 2009 a las 6:37 amY luego llamas al metodo y modificas su (estado) valor como quieras.
Jose Dueñas
Hola Franco,
22 de abril, 2009 a las 9:12 amefectivamente, pero se trataba de ver cómo hacerlo para variables de tipo simple, no objetos. Ya sabemos que los objetos se pasan siempre por referencia.
Gonzalo
Sin embargo los tipos basicos encapuslados (Integer, Character, etc) no pueden modificar su valor, asi que tampoco vale pasar un Integer.
2 de julio, 2009 a las 8:25 pmParece que el array es la mejor opcion, a fin de cuentas un array de un elemento no es mas que un puntero a ese elemento
robertito
Buenas,
19 de agosto, 2009 a las 8:08 pmme he encontrado con un pequeño problema referente a todo esto…. tengo un objeto y quiero crear otro igual, pero OTRO. si hago
Objeto a = new Objeto();
Objeto b = a;
si modifico b, tambien se modifica a. como podria evitar esto? crear una copia de este objeto, y no crear otra referencia al mismo objeto?
muchas gracias…
Miguel Vegallero
Robertito, fácilmente:
Objeto a = new Objeto(); // Se crea el objeto a
17 de septiembre, 2009 a las 3:05 am.
. // Se modifica el objeto a
.
Objeto b = new Objeto(a); // Se crea el objeto b, que es clon de a
Juan
Saludos Jose, mi duda es si dices que en java las variables simples u objetos se pasan simpre por valor, porque en tu segundo comentario dices “Ya sabemos que los objetos se pasan siempre por referencia.”. me podrias aclarar eso por favor. Gracias
24 de octubre, 2009 a las 11:12 pmJose Dueñas
Hola Juan,
25 de octubre, 2009 a las 1:07 amsi, en realidad quería decir que se pasa por valor la referencia al objeto (su dirección).
CESARS
Hola, tengo una pregunta, es que nececito cambiar una variable de tipo int a String, y despues de convertirla mostrarla en una textfield.
asi voy en el momento.
String dato,resultado;//variables
int intdato,intresultado;//variables
dato= textField.getString();//tomo el valor del texField
intdato=Integer.parseInt(dato);//aqui cambio la variable string a entero
intresultado = intdato*intdato; //aquie hago la operacion.
pero no se como convertir la variable intresultado en una variable de tipo String y mostrarla en otro textField(1).
31 de octubre, 2009 a las 6:35 pmPat
Querido José,
Gracias por el ejemplo que presentas; es muy claro e ilustra perfectamente la problemática descrita.
Sin embargo, no estoy de acuerdo con la semántica que has utilizado. En tu artículo, dices:
“(…) en Java las variables, ya sean simples u objetos, se pasan siempre por valor.”
A mi parecer, esta frase puede llevar a error. En mi opinión, en los parámetros a funciones en Java:
“Los objetos se pasan por referencia” -> Es decir, el objeto se pasa al método utilizando una referencia a él.
“La referencia a un objeto se pasa por valor” -> Es decir, se realiza una copia de la referencia al objeto.
Un saludo
26 de diciembre, 2009 a las 6:14 pmJav
Solucion al problema de paso por referencia de tipos primitivos: C#.
Jajaja
15 de septiembre, 2010 a las 11:26 pm