General

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

Después de varios meses de no escribir en el Blog, he decidido responder a una serie de cuestionamientos sobre el tema de “Paso de parámetros en Java” donde desafortunadamente existe mucha confusión al respecto y por ende he recibido comentarios en donde dicen que yo no tengo idea de lo que hablo. Pero bueno, aclaremos ahora todo esto y veamos en donde esta el meollo del asunto o el asunto del meollo.

Ocupare material elaborado por mi en un curso que impartí sobre Java. Barreré como a la hojarasca!

 

Introducción

image

Variables primitivas.

Básicamente consisten en variables de alguno de los tipos primitivos.

Variables de Referencia.

También se les llama variables de objeto. Estas variables no son el objeto mismo, son solo una referencia al objeto. Imaginemos tener una variable de tipo Date.

private Date fechaLimite;

Al crear el objeto con el operador new, sucede algo como lo mostrado en la imagen de abajo.

image

fechaLimite no es el objeto en si, más bien es una referencia al objeto Date.

En Java, el valor de toda variable de objeto es una referencia de un objeto que reside en algún otro lugar. El valor proporcionado por el operador new también es una referencia.

La expresión new Date() crea un objeto del tipo Date, y su valor es una referencia del objeto recién creado. Esa referencia se almacena entonces en la variable fechaLimite. Las referencias de objeto son equivalentes a los punteros de C++, sin embargo, en Java no es posible manejar punteros y la administración de memoria es una tarea del Garbage Collector.

 

Existe Existe en la terminología de las Ciencias Computacionales para el paso de parámetros a los métodos.

Paso por valor o copia. Significa que el método obtiene solamente el valor (una
copia) que proporciona quien hace la llamada.

● Paso por Referencia. Significa que el método recibe la ubicación de la variable
que proporciona quien hace la llamada.

 

Ahora si, una vez aclarado lo anterior, podemos comenzar a desmentir a esa falsa creencia que tienen algunos de mis lectores del blog y muchísima más gente conocedora de C++ pero no de Java y piensan que todo es igual en Java.

12 comentarios en “I. Paso de parámetros en Java: Por Valor

  1. Hola yo creo que si se puede pasar valores por referencia…. O si no expliquenme esto

    int bytesleidos;
    char [] charleidos = new char [4*1024];
    //digamos que ya tenemos instaciado un objeto de tipo bufferedreader llamado entrada…..

    bytesleidos=entrada.read (charleidos);

    bien como vemos en bytesleidos se guarda el numero de bytes leidos en el archivo x, si esta archivo tiene 726 bytes en bytesleidos = 726. Igualmente en el arreglo charleidos deben estar los caracteres leidos en el archivo x….

    La unico forma (que veo) es que charleidos sea pasado por referencia y en ese caso sea produzca una especie de retorno multiple..

    como bien sabemos la funcion read retorna un entero,
    pero si depues de lo anterior agregamos

    for(int i=0; i<bytesleidos; i++) System.out.print(""+charleidos[i])

    aparece todo el contenido del archivo de texto…

    Les dejo la duda…..
    si hay alguna respuesta les agradeceria
    andres.1123@yahoo.com

  2. Cuando pasas un objeto por parametro pasas la direccion de memoria donde se encuentra el objeto almacenado en memoria, dentro de la función podremos utilizar la referencia para modificar el objeto, ya que con lo que realmente trabajamos es con la direccion de memoria donde se almacena el objeto por lo que cualquier cambio que se efectue dentro de la función se vera fuera de esta.

  3. no estas pasando una copia del objeto, ni una copia de la referencia estas pasando la direccion de memoria donde esta almacenado el objeto ORIGINAL.

  4. perdon, lo que pasas es una copia por valor de la REFERENCIA, por lo que estas pasando una copia de la dirección de memoria donde esta almacenado el objeto, luego modificas el objeto siendo visibles los cambios fuera de la función.

  5. Agradecería a windoctor que contestara lo que “mis colegas” en java han dicho, me parece una falta de educación el poner cartas sobre la mesa y no querer jugar.

    Admito que windoctor tiene razón en cuanto a que siempre el paso de parámetros es por valor,
    pero hay que ver la diferencia en los tipos primitivos y en los de tipo referencia o “tipo objeto”.
    Saludos y no se compliquen mucho la vida😀

  6. Hola Gustavo!

    Hay cosas mayores que considerar falta de educación que el hecho de no responder a unos cuestionamientos. Si no los respondo es sencillamente por el hecho de que dadas las referencias que puse al final de la tercera parte del artículo y aun así aferrarse a las ideas de que Java también usa el paso por referencia es algo inútil. Las referencias de donde me baso para afirmar lo que digo hablan por si solas y creo que el artículo leido en su totalidad en las 3 partes, es más que contundente como para volver a debatir sobre lo que ya esta dicho🙂

    Saludos!!

  7. Hola WinDoctor, le informo que usted tiene toda la razón en lo que dice, si alguien ignora algo sobre el lenguaje java, que consulte los escritos de su creador, ya que nadie mas que él puede conocer mejor su invento! Sls.

  8. Confirmo que no tienes ni idea de lo que hablas windoctor en java los tipos primitivos se pasan por valor y los objetos se pasan por referencia, de toda la vida de dios.

  9. Y se puede demostrar con el siguiente codigo

    -Tipos primitivos aun usados como objetos:

    public class Main {
    public void cambio(String c){
    c = “hhhhhhhhhhh”;
    }
    public static void main(String[] args) {
    String c= new String(“ddddddddddd”);

    new Main().cambio(c);
    System.out.println(c);
    }
    }

    Resultado de la aplicacion “dddddddddddd” luego c se pasa por valor.

    -Objetos:

    public class Main {
    public void cambio(Cadena c){
    c.cadena=”hhhhhhhhhhhhh”;
    }
    public static void main(String[] args) {

    Cadena c =new Cadena(“ddddddddddd”);
    new Main().cambio(c);
    System.out.println(c.cadena);
    }
    }

    class Cadena {
    public String cadena;
    public Cadena(String c){

    this.cadena= c;
    }
    }

    Resultado de la aplicacion “hhhhhhhhhhhhh” luego c se pasa por referencia.

    Mas claro agua

  10. Francisco,

    Existe una diferencia entre “Objetos” y “referencia” de objetos, por lo cual no es lo mismo decir que los objetos en java se pasan por referencia, a decir que los objetos en java se pasan por copia, solo que se pasa una copia de la referencia.

    Primeramente hay que aclarar que String es un Objeto hecho y derecho y no un tipo primitivo. Despues, un String es un objeto inmutable tal y como se describe en la documentación de Java. Por lo cual no es posible cambiar el valor de un String toda vez que ya ha sido creado. Si hacemos esto:

    String cadena = “algo”;
    cadena = “otra cosa”;

    El compilador crea otro objeto String y sobre ese hace el cambio. Por ello es que un String resulta ineficiente para concatenar muchas cadenas y en su lugar se debe usar StringBuilder. Esta es la razón por la cual el valor no cambia en el ejemplo que propones y no tanto por que se pase por copia o por referencia.

    El segundo ejemplo también es fácil de comprobar el error. Vamos a llamarle c1 a la referencia de Cadena que creas dentro del Main y c2 a la referencia de Cadena que creas en el metodo cambiar. En el método main crea en memoria un objeto Cadena con el valor “ddddd” y c1 hace referencia a este objeto. Cuando invocas al método cambiar se pasa una “copia” de la referencia, es decir, ahora tienes a dos referencias, c1 y c2 apuntando al mismo objeto Cadena. Luego desde c2 se asigna otro valor al String, pero c2 que es una copia de c1 apunta al mismo objeto Cadena, por ello cuando vuelve la invocacion al metodo main, c1 tiene otro valor. Sin embargo esto no quiere decir que es por que haya sido pasado por referencia, solo se paso una copia de la referencia y esto se comprueba de la siguiente manera:

    Definir y crear un objeto Cadena en el constructor.

    Cadena cad;
    public Main(){
    cad = new Cadena(“hola”);
    }

    El método “cambio” sustituirlo por este otro:

    public void cambio(Cadena c){
    c = cad;
    System.out.println(c.cadena);
    }

    El método main queda igual:

    public static void main( String[] args )
    {
    App app = new App();

    Cadena c =new Cadena(“ddddddddddd”);
    app.cambio(c);
    System.out.println(c.cadena);
    }

    Si el paso de objetos en java se hiciera por verdadera referencia, entonces estas de acuerdo que antes de invocar al método cambio c1 apunta a un objeto Cadena cuyo valor es “ddddd”. Una vez invocado el metodo “cambio” hacemos que c2 apunte a otro Objeto cadena con el valor “hola”. Dado que tu aseguras que el paso de objetos es por referencia entonces al hacer que c2 apunte a otro objeto diferente, por ende c1 tambien apuntaria a ese nuevo objeto.

    Sin embargo, nos llevamos la sorpresa que el resultaod final es que c1 sigue valiendo “dddddddd” y no “hola”… ¿Por qué?…. Por la sencilla razón que se paso una copia de la referencia y no la referencia como tal.

    Como te comento, tu error es no saber distinguir los conceptos de referencia y objeto, copia de la referencia, puntero, etc.

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