Está en la página 1de 5

EN JAVA, EL PASO DE PARÁMETROS ES POR 

VALOR
Existe comúnmente la creencia errónea de que en Java es posible pasar parámetros por referencia, y no es así. Java
siempre pasa los parámetros por valor. Esta confusión se da debido a que todas las variables de objeto son referencias a
objetos [1]. En el libro “The Java Programming Language” de Ken Arnold y James Gosling (autores de Java), sección
2.6.1., tenemos la siguiente cita: “There is exactly one parameter passing mode in Java – pass by value – and that helps
keep things simple.” [2] (Existe un solo modo de paso de parámetros en Java – paso por valor – y eso ayuda a mantener
las cosas simples.).

Antes de continuar, vamos a recordar cuáles son las definiciones de paso por valor y paso por referencia: [3]:

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;
35 }
36
37 public void setParam1(String param1) {
38 this.param1 = param1;
39 }
40
41 public String toString() {
42 return "[param1 = " + this.getParam1() + "]";
43 }
44
45 }

Remitámonos a línea 20. Declaramos una variable pass, de tipo ValorOReferencia, con su único atributo param1
inicializado con el valor “Objeto inicial.”. En la línea 23, presentamos el objeto en pantalla, y se muestra el valor con el
que fue declarado.

SALIDA DEL PROGRAMA:


Entender que Java pasa parámetros por valor:
Antes de modificar pass es: [param1 = Objeto inicial.]

Ahora, en la línea 24 pasamos nuestra variable pass al método cambiarObjeto, método que tiene un parámetro formal de
tipo ValorOReferencia. En dicho método, en la línea 11, se realiza una asignación

objeto = new ValorOReferencia("Este es un nuevo objeto.");

, se presenta el objeto “modificado” y el control regresa al método main.

SALIDA DEL PROGRAMA:


Luego de "reasignar" pass: [param1 = Este es un nuevo objeto.]

Suponiendo que el paso de parámetros en Java fuera por referencia, la referencia pass apuntaría ahora a un nuevo objeto
con el valor “Este es un nuevo objeto.”. Pero, al regresar al método main, en la línea 25, presentamos de nuevo pass, 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 pasar pass y vamos a modificar solamente su único atributo. En la línea 28, pasamos pass al método
cambiarParam1, en donde tenemos la sentencia

objeto.setParam1("Este es un nuevo valor para param1.");

en la línea 16. Así, se ha modificado el valor del atributo param1, y al volver al método main, presentamos pass otra vez:

SALIDA DEL PROGRAMA:

Ahora vamos a cambiar sólo param1:


De seguro param 1 ha cambiado: [param1 = Este es un nuevo valor para param1.]
Parece difícil, pero no lo es.

Al ver esta última operación, quizá alguien pueda decir que Java sí pasa parámetros por referencia, ya que se modificó el
atributo del objeto, pero estaría equivocado: ¿Por qué en cambiarObjeto la variable pass no sufre ninguna modificación, y
en el método cambiarParam1 su atributo se ve efectivamente modificado? Porque Java no pasa objetos como
parámetros [4], sino copias de las referencias a esos objetos. Exacto. Java pasa parámetros por valor. Pasa referencias a
objetos por valor.

Vamos a explicar lo que hacen nuestros métodos cambiarObjeto(ValorOReferencia objeto) y


cambiarParam1(ValorOReferencia objeto).

cambiarObjeto(ValorOReferencia objeto)

En main, declaramos una variable

ValorOReferencia pass = new ValorOReferencia("Objeto inicial.");

Se ha creado un objeto ValorOReferencia en cierta posición de memoria y la forma de acceder a él es usar la referencia
pass.

Omito los métodos setters, getters y toString() en el diagrama porque no intervienen en la explicación de este método.
Este método tiene un parámetro formal ValorOReferencia objeto. Como Java pasa parámetros por valor tenemos que
objeto, el parámetro formal de cambiarObjeto, es una copia de la referencia pass, es un alias, mas no es la referencia pass.
Siguiente a la llamada al método lo que tenemos es lo siguiente:

objeto es una copia de la referencia pass, es otra referencia que apunta al mismo lugar. Al ejecutar la sentencia

objeto = new ValorOReferencia("Este es un nuevo objeto.");

lo que hacemos de hecho es esto:

objeto, que originalmente era una copia de la referencia pass, apunta ahora a un nuevo objeto creado en otra posición de
memoria. Es por eso que de vuelta al main, el objeto apuntado por pass no ha cambiado.

cambiarParam1(ValorOReferencia objeto)
Desde el método main pasamos a cambiarParam1 la referencia pass:

Incluyo el método setter setParam1(String param1) porque interviene en esta explicación. cambiarParam1 tiene un
parámetro formal ValorOReferencia objeto, que es un alias de pass.

Al ejecutar la sentencia

objeto.setParam1("Este es un nuevo valor para param1.");

, lo que estamos haciendo es invocar al método setParam1 del objeto apuntado por la referencia objeto. Es por eso que el
atributo param1 del objeto referenciado por pass es efectivamente modificado.

Cuando declaramos variables, por ejemplo,

ValorOReferencia valoRef = new ValorOReferencia();

, no declaramos un objeto ValorOReferencia, sino una referencia a un objeto ValorOReferencia. Java tiene punteros
(referencias a objetos), pero no es posible manejarlos con la aritmética con que se manejan en C++ [5]. No obstante, la
implementación de estos punteros es similar en ambos lenguajes:

 Una sentencia Java ValorOReferencia valORef; es exactamente igual a una sentencia C++
ValorOReferencia *valORef;.
 Una sentencia Java valORef.cambiarParam1(“Otro valor.”); es exactamente igual a una sentencia C++
valORef -> cambiarParam1(“Otro valor.”);. [6]

Hay que tener claro entonces, que cuando se escribe una sentencia del estilo

cualquierFuncion(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 parámetro [7], ni parámetros
por referencia.
Referencias:

[1] UNDERSTANDING THAT PARAMETERS ARE PASSED BY VALUE AND NOT BY REFERENCE,
DeveloperWorks, Peter Haggar, http://www.ibm.com/developerworks/library/j-praxis/pr1.html

[2] PASS BY VALUE SEMANTICS IN JAVA APPLICATIONS, Peter Haggar, DeveloperWorks


http://www.ibm.com/developerworks/java/library/j-passbyval/

[3] PASS BY VALUE SEMANTICS IN JAVA APPLICATIONS, Peter Haggar, DeveloperWorks


http://www.ibm.com/developerworks/java/library/j-passbyval/

[4] PASS BY VALUE SEMANTICS IN JAVA APPLICATIONS, Peter Haggar, DeveloperWorks


http://www.ibm.com/developerworks/java/library/j-passbyval/

[5] JAVA IS PASS-BY-VALUE, DAMMIT!, JavaDude Articles,

http://javadude.com/articles/passbyvalue.htm

[6] JAVA IS PASS-BY-VALUE, DAMMIT!, JavaDude Articles,

http://javadude.com/articles/passbyvalue.htm

[7] PASS BY VALUE SEMANTICS IN JAVA APPLICATIONS, Peter Haggar, DeveloperWorks


http://www.ibm.com/developerworks/java/library/j-passbyval/

También podría gustarte