General

III. Paso de parámetros en Java: Por Valor

Explicábamos en la segunda parte de este artículo que lo que realmente se pasa es una copia de la referencia. La explicación gráfica del ejemplo anterior de lo que sucede en memoria es la siguiente.

image

 

 

 

 

 

 

 

 

 

Recordemos que en nuestra primera entrega explicamos lo que es una “referencia de objeto” y decíamos que una referencia de objeto apunta al Objeto.

Entonces cuando creamos al objeto “ascari”, este es solo una referencia a un objeto Empleado. Cuando invocamos al método triplicarSueldo y le pasamos como parámetro al objeto ascari, no le estamos pasando la dirección de memoria de “ascari”. Lo que sucede es que se hace una copia de la referencia “ascari” y esta copia se pone en “x”.

Lo anterior es la piedra de tropiezo para muchos, y es lo que les causa confusión. El hecho de que Java maneje el concepto de “referencia de objeto” es lo que hace pensar que Java hace un paso de parámetros por referencia, es decir, que se le pasa la dirección de memoria. Sin embargo, una referencia de objeto es un apuntador a un Objeto ubicado en algún otro lugar de memoria.

Como lo comentábamos, cuando “ascari” es pasado al método triplicarSueldo, no quiere decir que a “x” le sea asignada la dirección de memoria de “ascari”. Como lo ilustra la figura de arriba, se hace una copia de la referencia! Por lo tanto existen dos referencias que apuntan a un objeto Empleado.

Técnicamente esta mal dicho si decimos “modificar x” ó “modificar ascari” ya que en ningún momento estamos modificando a “x” o “ascari” ya que estas son solo referencias a un objeto Empleado, lo que realmente se modifica es el objeto Empleado.

Ahora como seguramente muchos pensaran que todo lo anterior es absurdo, hay que realizar un último ejemplo para demostrar de forma contundente que los objetos no son pasados por valor.

Tercer Ejemplo.

Hagamos un método llamado intercambiar que reciba dos objetos Empleado y que intente intercambiar a los empleados.

image

image

Si Java hiciera un paso de parámetros por “referencia” el resultado de este ejemplo es que “a” terminaría refiriéndose a Beto y “b” terminaría refiriéndose a Ascari, sin embargo no es así. ¿Qué esta pasando internamente en memoria? ¿Por qué en el ejemplo anterior si existe un cambio en la variable que hace la llamada y  en este no?

Si el paso de parámetros Si el paso de parámetros fuera por referencia, ocurriría algo como esto.

image

Si Java hiciera un paso de parámetros por referencia, entonces “x” obtendría la dirección de memoria de “a” y “y” obtendría la dirección de memoria de “b”. Entonces cuando en el método “intercambiar” intentemos hacer que “x” apunte al Empleado Benito y que “b” apunte al Empleado “Ascari”, por ende “a” también apuntaría a “Benito” y “b” apuntaría a “Ascari”. (Figura de abajo).

image

Sin embargo, podemos comprobar que lo anterior no funciona. a sigue refiriéndose a Ascari y b a Benito. Por lo tanto, Java no acepta un paso de parámetros por referencia sino por copia o valor, pero lo que se copia es la referencia del objeto.

Ahora veamos lo que en realidad esta pasando.

image

Observamos que existe una copia de las referencias a y b. Estas referencias son copiadas en x e y. Ahora “x” apunta a Ascari y “y” a Benito.

image

Pero inmediatamente en el método “intercambiar” se realiza el intercambio.

image

Ahora vemos como “x” apunta a “Benito” y “y” apunta a “Ascari”.. Sin embargo no perdamos el foco de que tanto “a” como “b” siguen apuntando al mismo objeto!!!!!!!!!

Lo anterior demuestra de forma contundente que Java NO realiza el paso de parámetros por referencia, sino por copia, pero lo que sucede es
que se hace una copia de las referencias de objeto.

Desafortunadamente autores de libros sostiene que Java realiza paso de parámetros por referencia para los objetos.

Algunos autores son:
● Francisco Javier Ceballos
● Agustín Froufre

Afortunadamente hay autores que con toda la autoridad desmienten lo anterior. Algunos de ellos son:

● Gary Cornell
Autor y coautor de más de una veintena de libros. Posee el
titulo de Doctor otorgado por la Brown University y ha sido
científico visitante en IBM.

● Deitel & Deitel
Toda una autoridad y sus libros son un clásico
en lo tocante a Java y C++.

Pero si todavía queremos más referencias para creer, existen libros de preparación para el EXÁMEN DE CERTIFICACIÓN “SUN CERTIFIED JAVA PROGRAMMER” tal es el caso del libro “SCJP Exam for J2SE 5” del Dr. PAUL SANGHERA, donde en la página 124 afirma lo siguiente.

“The key point to remember is that regardless of whether the passed variable is a primitive or a reference variable, it is always the copy of the variable, and not the original variable itself. Technically speaking, it is pass-by-value and not pass-by-reference within the same virtual machine.”

 

Más adelante, en la página 125 comenta lo siguiente.

“Recall that an object reference variable points to an object, and it is not the object itself. When you pass a reference variable in a method, you pass a copy of it and not the original reference variable.”

Ahora bien, para los necios, por si esto fuera poco, el mismo creador de Java, sostiene que Java solo utiliza el paso de parámetros por valor.

““There is exactly one parameter passing mode in Java – pass by value – and that helps keep things simple.”

 

Podemos dar por hecho que hemos desmentido una creencia errónea y a partir de ahora, no seremos engañados por muchas páginas de internet y de personas que dicen que Java acepta el paso de parámetros por valor y por referencia.

 

Saludos!!

10 comentarios en “III. Paso de parámetros en Java: Por Valor

  1. Es muy fino el tema, pero está bien explicado. Básicamente es un trabalengua, que se resume en que lo que Java, es en realidad una copia de las referencias.

    Lo que pasa es que luego en los métodos se puede modificar al objeto, entonces de allí la confusión de que parece que se envia una referencia.

    De todas formas, con los ejemplos dados no quedan dudas.

    Excelente trabajo, para un tema que parece tan trivial pero que no lo es.

  2. Concuerdo con los anteriores comentario. Este es un articulo excelente que deja bien puestos los puntos sobre la mesa. No es trivial, pues que los buenos fundamentos fortalecen tu habilidad como desarrollador. Tambien tengo que replantear lo que dije en el comentario de la seccion 2 de este articulo, definitivamente decir que el objeto se pasa por referencia y que o que se pasa es una copia de la referencia al objeto son dos cosas completamente diferente como queda demostrado en el tercer ejemplo.

  3. excelente tu aclaracion!!! es algo tan tan importante, y que sin embargo muchos que ya tenemos tiempo en esto de java lo desconocemos
    muchas gracias por tu aclaracion
    Tienes razon, tengo un libro de Francisco Ceballos, y el nos miente diciendo que existen dos formas de pasar parametros en java

  4. Desafortunadamente autores de libros sostiene que Java realiza paso de parámetros por referencia para los objetos.

    Algunos autores son:
    ● Francisco Javier Ceballos

    En que parte de sus libros esta equivocado ?

    saludos !

  5. Todos los ejemplos están perfectamente manipulados para no mostrar la realidad, que no es otra que Java pasa los parámetros por referencia.

    Por favor, lee completamente los libros a los que haces referencia y plantea correctamente tus pruebas. Verás que estás equivocado y te evitarás cometer errores en tu programación.

    Saludos,

    Raúl.-

    1. Nada de eso Raúl, los libros a los que hago referencia, son claros y tienen comentarios explícitos.

      “Recall that an object reference variable points to an object, and it is not the object itself. When you pass a reference variable in a method, you pass a copy of it and not the original reference variable.”

      Solo debes tener claro la diferencia entre Objeto y Referencia de objeto. Cuando tienes la diferencia clara, sabrás que Java maneja el paso de parámetros por Copia… es decir, hace una copia de la referencia del objeto.

      Saludos!!

  6. Buenísima aclaración, he llegado a este sitio buscando información sobre cómo podría conseguir un paso por referencia y ahora que leo esto y entiendo el funcionamiento real sé cómo resolver mi problema, y sé que ese paso por referencia que buscaba no existe. Supongo que al venir de C/C++ tengo algunos conceptos confusos con respecto a Java, ¡gracias!

  7. Sabes como funciona internamente una llamada a una función? Te lo voy a explicar para que lo entiendas un poco:

    Cuando se hace una llamada a una función se ponen los parametros en el top de la pila. Entonces si es un Objeto A, se pone su direccion de memoria en vez de hacer una copia (aquí tienes tu copia de la referencia). Luego existe una pequeña diferencia entre FUNCIONES y ACCIONES(void) sabes. Las FUNCIONES DEVUELVEN un valor y la ACCIONES no. O sea que como una ACCION no devuelve nada, no puedes devolver el cambio de referencia que haces internamente. Solamente los cambios en el objetos son visibles.

    Así que tienes razón, pero has desarrollado mal tu hipotesis, my mal tu demostración y tus conclusiones no son del todo correctas.

    Un saludo

    1. Hola Gutzi,

      Agradezco tus comentarios, pero en realidad no tiene caso entrar en controversias. Solo 1 es la verdad en este tema y si el mismo Gosling lo dice, mejor creamosle a él antes que a nadie.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s