5
PASÓ DE PARAMETROS POR VALOR Y REFERENCIA Paso por valor significa que cuando un argumento se pasa a una función, la función recibe una copia del valor original. Por lo tanto, si la función modifica el parámetro, sólo la copia cambia y el valor original permanece intacto. Paso por referencia significa que cuando un argumento se pasa a una función, la función recibe la dirección de memoria del valor original, no la copia del valor. Por lo tanto, si la función modifica el parámetro, el valor original en el código que llamó a la función cambia. Vamos a valernos de ejemplos para explicar el mecanismo con el que Java pasa parámetros a los métodos. Tenemos el siguiente programa Java: 1 public class ValorOReferencia { 2 3 private String param1 = new String(); 4 5 /** Creates a new instance of PassValueOrReference */ 6 public ValorOReferencia(String param1) { 7 this.setParam1(param1); 8 } 9 10 public static void cambiarObjeto(ValorOReferencia objeto) { 11 objeto = new ValorOReferencia("Este es un nuevo objeto."); 12 System.out.println("Luego de \"reasignar\" pass: " + objeto); 13 } 14 15 public static void cambiarParam1(ValorOReferencia objeto) { 16 objeto.setParam1("Este es un nuevo valor para param1."); 17 } 18 19 public static void main(String[] args) { 20 ValorOReferencia pass = 21 new ValorOReferencia("Objeto inicial."); 22 System.out.println("Entender que Java pasa parámetros por valor: "); 23 System.out.println("Antes de modificar pass es: " + pass); 24 ValorOReferencia.cambiarObjeto(pass); 25 System.out.println("De vuelta en main pass es: " + pass); 26 System.out.println("Ahora vamos a cambiar sólo param1:"); 28 ValorOReferencia.cambiarParam1(pass); 29 System.out.println("De seguro param 1 ha cambiado: " + pass); 30 System.out.println("Parece difícil, pero no lo es."); 31 } 32 33 public String getParam1() { 34 return param1;

Valor o Referencia

Embed Size (px)

DESCRIPTION

PROGRAMACION

Citation preview

PAS DE PARAMETROS POR VALOR Y REFERENCIAPaso por valorsignifica que cuando un argumento se pasa a una funcin, la funcin recibe una copia del valor original. Por lo tanto, si la funcin modifica el parmetro, slo la copia cambia y el valor original permanece intacto.

Paso por referenciasignifica que cuando un argumento se pasa a una funcin, la funcin recibe la direccin de memoria del valor original, no la copia del valor. Por lo tanto, si la funcin modifica el parmetro, el valor original en el cdigo que llam a la funcin cambia.Vamos a valernos de ejemplos para explicar el mecanismo con el que Java pasa parmetros a los mtodos.Tenemos el siguiente programa Java:1 public class ValorOReferencia {23 private String param1 = new String();45 /** Creates a new instance of PassValueOrReference */6 public ValorOReferencia(String param1) {7 this.setParam1(param1);8 }910 public static void cambiarObjeto(ValorOReferencia objeto) {11 objeto = new ValorOReferencia("Este es un nuevo objeto.");12 System.out.println("Luego de \"reasignar\" pass: " + objeto);13 }1415 public static void cambiarParam1(ValorOReferencia objeto) {16 objeto.setParam1("Este es un nuevo valor para param1.");17 }1819 public static void main(String[] args) {20 ValorOReferencia pass =21 new ValorOReferencia("Objeto inicial.");22 System.out.println("Entender que Java pasa parmetros por valor: ");23 System.out.println("Antes de modificar pass es: " + pass);24 ValorOReferencia.cambiarObjeto(pass);25 System.out.println("De vuelta en main pass es: " + pass);26 System.out.println("Ahora vamos a cambiar slo param1:");28 ValorOReferencia.cambiarParam1(pass);29 System.out.println("De seguro param 1 ha cambiado: " + pass);30 System.out.println("Parece difcil, pero no lo es.");31 }3233 public String getParam1() {34 return param1;35 }3637 public void setParam1(String param1) {38 this.param1 = param1;39 }4041 public String toString() {42 return "[param1 = " + this.getParam1() + "]";43 }4445 }Remitmonos a lnea 20. Declaramos una variablepass, de tipoValorOReferencia, con su nico atributoparam1inicializado con el valor Objeto inicial.. En la lnea 23, presentamos el objeto en pantalla, y se muestra el valor con el que fue declarado.Salida del programa:

Entender que Java pasa parmetros por valor:Antes de modificar pass es: [param1 = Objeto inicial.]Ahora, en la lnea 24 pasamos nuestra variablepassal mtodocambiarObjeto, mtodo que tiene un parmetro formal de tipoValorOReferencia. En dicho mtodo, en la lnea 11, se realiza una asignacinobjeto = new ValorOReferencia("Este es un nuevo objeto.");, se presenta el objeto modificado y el control regresa al mtodomain.Salida del programa:Luego de "reasignar" pass: [param1 = Este es un nuevo objeto.]Suponiendo que el paso de parmetros en Java fuera por referencia, la referenciapassapuntara ahora a un nuevo objeto con el valor Este es un nuevo objeto.. Pero, al regresar al mtodomain, en la lnea 25, presentamos de nuevopass, y vemos que el valor con el que fue originalmente declarado se mantiene.Salida del programa:De vuelta en main() pass es: [param1 = Objeto inicial.]Ahora, vamos a pasarpassy vamos a modificar solamente su nico atributo. En la lnea 28, pasamospassal mtodocambiarParam1, en donde tenemos la sentenciaobjeto.setParam1("Este es un nuevo valor para param1.");en la lnea 16. As, se ha modificado el valor del atributoparam1, y al volver al mtodomain, presentamos pass otra vez:Salida del programa:Ahora vamos a cambiar slo param1:De seguro param 1 ha cambiado: [param1 = Este es un nuevo valor para param1.]Parece difcil, pero no lo es.Al ver esta ltima operacin, quiz alguien pueda decir que Java s pasa parmetros por referencia, ya que se modific el atributo del objeto, pero estara equivocado: Por qu encambiarObjetola variablepassno sufre ninguna modificacin, y en el mtodocambiarParam1su atributo se ve efectivamente modificado?Porque Java no pasa objetos como parmetros [4], sino copias de las referencias a esos objetos. Exacto. Java pasa parmetros por valor. Pasa referencias a objetos por valor.Vamos a explicar lo que hacen nuestros mtodoscambiarObjeto(ValorOReferencia objeto)ycambiarParam1(ValorOReferencia objeto).cambiarObjeto(ValorOReferencia objeto)En main, declaramos una variableValorOReferencia pass = new ValorOReferencia("Objeto inicial.");Se ha creado un objetoValorOReferenciaen cierta posicin de memoria y la forma de acceder a l es usar la referenciapass.

Omito los mtodos setters, getters y toString() en el diagrama porque no intervienen en la explicacin de este mtodo. Este mtodo tiene un parmetro formalValorOReferencia objeto. Como Java pasa parmetros por valor tenemos que objeto, el parmetro formal decambiarObjeto, es una copia de la referenciapass, es un alias, mas no es la referenciapass. Siguiente a la llamada al mtodo lo que tenemos es lo siguiente:

objeto es una copia de la referenciapass, es otra referencia que apunta al mismo lugar. Al ejecutar la sentenciaobjeto = new ValorOReferencia("Este es un nuevo objeto.");lo que hacemos de hecho es esto:

objeto, que originalmente era una copia de la referenciapass, apunta ahora a un nuevo objeto creado en otra posicin de memoria. Es por eso que de vuelta almain, el objeto apuntado porpassno ha cambiado.cambiarParam1(ValorOReferencia objeto)Desde el mtodomainpasamos acambiarParam1la referenciapass:

Incluyo el mtodo settersetParam1(String param1)porque interviene en esta explicacin.cambiarParam1tiene un parmetro formalValorOReferencia objeto, que es un alias depass.

Al ejecutar la sentenciaobjeto.setParam1("Este es un nuevo valor para param1.");, lo que estamos haciendo es invocar al mtodosetParam1del objeto apuntado por la referenciaobjeto. Es por eso que el atributoparam1del objeto referenciado por pass es efectivamente modificado.Cuando declaramos variables, por ejemplo,ValorOReferencia valoRef = new ValorOReferencia();, no declaramos un objetoValorOReferencia, sino una referencia a un objetoValorOReferencia. Javatienepunteros (referencias a objetos), pero no es posible manejarlos con la aritmtica con que se manejan en C++. No obstante, la implementacin de estos punteros es similar en ambos lenguajes: Una sentencia JavaValorOReferencia valORef;es exactamente igual a una sentencia C++

ValorOReferencia *valORef;. Una sentencia JavavalORef.cambiarParam1(Otro valor.);es exactamente igual a una sentencia C++valORef -> cambiarParam1(Otro valor.);Hay que tener claro entonces, que cuando se escribe una sentencia del estilocualquierFuncion(CualquierTipo argumento);en Java, lo que se pasa no es un objeto, sino una copia de la referencia al objeto. Es importante no confundirnos.Java pasa objetos por referencia (pasa las referencias a los objetos), pero nunca pasa un objeto como parmetro [7], ni parmetros por referencia.