Mundo Byte

Acercando el conocimiento de TI en términos sencillos

Parámetros en Java: ¿Valor o Referencia?

Hoy revisando algunos libros de Java, me encontré con algunos en donde sorprendentemente dicen una GRAN mentira. De hecho, muchos sitios en internet manejan que el paso de parámetros en Java se hace de dos formas:

  1. Si se tratan de tipos primitivos como int, double, etc. el paso se da por valor o copia.
  2. Si se tratan de Objetos (en realidad son referencias a objetos) entonces el paso de valor se hace por referencia.

NO hay nada más equivocado que esta idea, lo lamentable es que incluso sean los autores de libros, los “conocedores” y expertos de la materia los que caigan en tan infantil error. Uno de los autores de los que hablo es un Español muy conocido cuyo nombre empieza con F…. otro autor que me parece es mexicano y si bien recuerdo es de la misma editorial que el primer autor que menciono y cuyo apellido también empieza con la letra F afirma del mismo modo que Java hace el paso de parámetros por referencia y cuyo libro/tutorial esta pegado en la página de un Instituto Tecnológico de aqui en México.

Y bueno ni se digan de varias páginas en donde se habla de lo mismo, por ejemplo: http://es.wikibooks.org

En fin, encontré un artículo que me parecio interesante: http://jpangamarca.wordpress.com/cafe-java/en-java-el-paso-de-parametros-es-por-valor/

donde desmiente ese mito de que Java hace el paso de parámetros por Referencia, dejando en claro que únicamente se hace por VALOR.

Si alguno tiene dudas sobre este tema de las Referencias de Objetos, comentela aqui y en la medida de mi tiempo trataré de brindarle alguna explicación.

 

NOTA DEL DÍA 29 DE JUNIO DEL 2009.

Dada la discución y confusión que existe en los comentarios de este tema, escribi un artículo dividido en tres partes en donde demuestro de forma contundente que Java no realiza un paso de parámetros por referencia.

Espero que con esto, quede aclarado todo este tema. Principalmente hubieron algunas personas que me acusaron de no tener idea de lo que digo :D… pero bueno, este artículo les demuestra lo contrario.

http://mundobyte.wordpress.com/2009/06/29/i-paso-de-parmetros-en-java-por-valor/

Saludos!!

About these ads

38 Respuestas a “Parámetros en Java: ¿Valor o Referencia?

  1. ignorante abril 7, 2008 en 1:22 pm

    Bueno, depende como se lo interprete. Los objetos sí se pasan por referencia, lo que se pasa por valor es la referencia al objeto.

    Igual estyo de acuerdo en que es bueno aclarar todo eso y no dar una visión parcial que puede llevar a confusiones.

  2. windoctor abril 7, 2008 en 3:26 pm

    Cuando se pasa un parámetro a otro método se hace una copia de la referencia y NO se le pasa la dirección de memoria (que es a lo que llamamos paso por referencia), pues si esto ultimo fuera verdad el siguiente método modificaria el valor original…

    public static void intercambiar(Empleado x, Empleado y)
    {
    Empleado temp = x;
    x = y;
    y = temp;
    }

    ……
    Empleado a = new Empleado(“Alicia”….);
    Empleado b = new Empleado(“Benito…);
    intercambiar(a,b)

    ¿Se refiere ahora “a” a Benito y b a alicia?… NO

    Pero como se trata de una COPIA de la referencia al objeto, unicamente se modifica la copia y no el original. SI se tratara de un paso por referencia, ambos serían el mismo objeto en si, por lo cual, al tratar de referenciar:

    x = y …. entonces también “temp” apuntaria al mismo objeto y por lo cual si habría una modificación al objeto original.

    saludos!!

    • Erwin junio 2, 2009 en 4:17 am

      Ja…, yo creía lo mismo de que solo era paso por valor. Pero que gran mentira y ese artículo si que es una farsa. Acomodado y utilizando objetos diferentes para confundir. La realidad es que JAVA si permite paso por referencia. Es puro manejo de punteros. Solo en los tipos primitivos y String en el paso de argumentos a métodos se maneja el paso por valor…, para cualquier otro objeto que no sea String se pasa es la referencia, ósea se le asigna el valor de la referencia a otra referencia. Ambas quedan apuntando al mismo objeto y con la segunda puedo modificar el objeto…, Según el mismo principio que allí explican eso es paso por referencia…, Y lo debato con quien sea…

      • japones junio 7, 2009 en 5:10 am

        SI quiere debatirlo con quien sea, usted debe ser más inteligente que el mismo
        James GOsling creador del lenguaje Java, quien realmente afirma que java
        sol tiene un paso de parámetros, y es por valor….

        Será que habrá que comparar curriculums para creer que usted es mejor y
        tiene la razón??

      • Francisco Chávez febrero 16, 2012 en 1:36 am

        Perdón, son principiante en java, pero tengo entendido que no maneja punteros.

    • pnwn agosto 14, 2012 en 10:59 pm

      Cuando pasas objetos se pasan por referencia lol tu comentario es false

    • Ester octubre 19, 2012 en 10:07 am

      Tienes toda la razón del mundo. Es un error demasiado extendido. Abajo he dejado un comentario de porqué es así.

      Saludos

  3. Juan Pablo Angamarca mayo 18, 2008 en 4:30 am

    Gracias por referenciar mi artículo. Saludos.

  4. martin javier castellanos mayo 21, 2008 en 6:57 pm

    he leido este articulo pero en parte tienen razon pero por otra parte están en un error fatal, pues es asi como lo aprecio y les dire el por qué.

    windoctor, segun el link y primer comentario, afirma que los objetos se pasan por valor y no por referencia.
    si observa el metodo…
    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 }
    en la linea 10, el método crea una variable “objeto” de tipo “ValorOReferencia” que apunta precisamente a la misma dirección de memoria. Dicha direccion de memoria (pass=direccion de memoria xyz, objeto=direccion de memoria xyz).
    Pero NOTESE que en la linea 11 asignamos con la funcion “new” una nueva direccion de memoria a la que apuntara “objeto”, por lo cual, a partir de este momento, objeto y memoria ya no apuntan a la misma direccion de memoria.
    Concluyo que NO ES VALIDO el tratar de afirmar que los parametros de objetos se hacen por VALOR.

    Con respecto a tu segundo comentario, windoctor, ese ejemplo me indica que tienes un concepto erroneo de como funcionan internamente los objetos, es decir, que sucede en memoria al declarar una variable de tipo “clase” y que sucede en memoria cuando se le aplica la funcion “new” a ese objeto.
    Al declarar una variable de tipo “clase”, en memoria reserva una localidad de memoria para almacenar en ella un valor que hace referencia a otra localidad de memoria.
    Cuando se aplica un “new” sobre una variable instanciada (“objeto”) de una clase, en memoria se reserva el tamaño del objeto para almacenar los valores de las propiedades del objeto, el cual sera referenciado por dicha variable instanciada (“objeto”).
    Analiza tu ejemplo bajo la siguiente suposicion de direcciones de memoria:
    “a” apunta a la dir. de mem. #AA
    “b” apunta a la dir. de mem. #BB
    El método intercambiar, al ser invocado, declara dos variables del mismo tipo que “a” y “b” llamadas “x” y “y”. Por lo tanto, “x” apunta a la dir. de mem. #AA y “y” apunta a #BB.
    La línea de “Empleado temp=x” hace lo siguiente: en memoria se reserva una localidad de memoria para “x” la cual almacenará una dir. de mem. que corresponde a un objeto de tipo “Empleado”; es decir, “temp” apunta a la dir. de mem. #AA.
    “x=y” hace que “x” apunte a la dir. de mem. #BB
    “y=temp” hace que “y” apunte a la dir. de mem. #AA, y al terminar el método, elimina la variable “temp” pero no el objeto, debido a que la dir. de mem. que tenía almacenada (#AA) esta referenciada por el objeto “y”.

    Ojo: “Asignación de objetos” no implica copiar las propiedades del objeto, solo implica que se asigna la misma referencia de mem. a la asignación de variable.

  5. windoctor mayo 21, 2008 en 9:53 pm

    De hecho y sin crear polèmica, me parece que en lo personal yo aprecio en usted na confusión incluso entre lo que es una clase y un objeto asi como su representacion en memoria.

    EL ejemplo que comentè, es del LIbro de Core Java de los autores Cay S. Horstmann y Gary Cornel, ambos cientificos respetables y consultores de Tecnologia Java.

    EN su libro tratan todo este tema que merece la pena analizar.

    LO malo que no tengo mucho tiempo de momento.

    saludos!

  6. IGNORANTE julio 14, 2008 en 4:01 am

    windoctor ………claramente estas hablando de algo que poco o nada entiendes.

  7. RoHer noviembre 8, 2008 en 6:23 pm

    Hola!!!
    Siguiendo su caso les quería comentar lo siguiente:
    Definitivamente, cuando pasamos por parámetro un Objeto (Java), lo que pasa por valor es la dir. de memoria en donde esta alojado el mismo.
    O sea el metodo “intercambiar(….)” antes mencionado, intercambia las referencias de las instancias pasadas por valor, pero al terminar la ejecución del metodo y volver al contexto de ejecución que invocó al metodo, los objetos que fueron como parametros del metodo “intercambiar(….)”, tendrán las dir. de memoria originales.

    Saludos.

    Les dejo un ejemplo:

    /** Ejemplo —- Class**/

    package oracle.tasa.pgc;

    public class MemTest {

    public class BaseIdDescDTO{
    private String description;

    public BaseIdDescDTO() {
    super();
    // TODO Auto-generated constructor stub
    }

    public String getDescription() {
    return description;
    }

    public void setDescription(String description) {
    this.description = description;
    }

    }

    public BaseIdDescDTO getBaseInstance(){
    return new BaseIdDescDTO();
    }

    public static void main(String []args){
    BaseIdDescDTO b1 = new MemTest().getBaseInstance();
    BaseIdDescDTO b2 = new MemTest().getBaseInstance();
    b1.setDescription(“1111″);
    b2.setDescription(“2222″);
    System.out.println(“contenido antes: ” + b1.getDescription() + “, ” + b2.getDescription());
    cambio(b1, b2);
    System.out.println(“contenido despues: ” + b1.getDescription() + “, ” + b2.getDescription());
    }

    public static void cambio(BaseIdDescDTO x, BaseIdDescDTO y){
    BaseIdDescDTO temp = x;
    x = y;
    y = temp;
    y.setDescription(“3333″);
    }
    }
    /** Fin class **/

    __ Obtendrán como salida:

    “contenido antes: 1111, 2222″
    “contenido despues: 3333, 2222″

  8. Nelson Guerra Alvarez junio 26, 2009 en 8:54 pm

    Windoctor. Dejame decirte que estas totalmente equivocado. Java si pasa parametros por referencia.
    Tu haces referencia a
    “En fin, encontré un artículo que me parecio interesante: http://jpangamarca.wordpress.com/cafe-java/en-java-el-paso-de-parametros-es-por-valor/“.
    Dejame decirte que Juan Pablo Angamarca (el creador del articulo) no posee los conocimientos necesarios de Java, y si lees detalladamente el ejemplo te daras cuenta que en el ejemplo se describe exactamente el paso de parametros por referencia no por valor.
    Lo que sucede es que tanto tu como Juan Pablo Angamarca parecen no haber trabajado nunca con el lenguaje C o C++, en donde se utilizaban punteros. los conocedores de estos lenguajes saben de lo que hablo, y sabran que Java viene de C y C++ y solo coloco una capa mas para manejar los punteros, para que los programadores no puedan apuntar a lugares que no corresponde (ya sea por que cometieron un error o no).

  9. windoctor junio 29, 2009 en 3:16 am

    HOLA A TODOS!

    DADA LA DISCUCIÓN Y CONFUSIÓN EXISTENTE EN ESTE TEMA, HE DECIDIDO ESCRIBIR UN ARTÍCULO DEMOSTRANDO EL ERROR QUE TIENEN MUCHOS AL PENSAR QUE JAVA HACE UN PASO DE PARÁMETROS POR REFERENCIA.

    DIVIDO EL ARTÍCULO EN 3 PARTES, EN LA TERCERA PARTE PONGO REFERENCIAS REALES DE AUTORES QUE DESMIENTEN ESTE ERROR.

    PRINCIPALMENTE PARA AQUELLOS QUE COMENTARON HACIA MI PERSONA DICIENDO QUE NO TENGO IDEA DE LO QUE HABLO, ESTE ARTÍCULO LES DEMOSTRARÁ EL ERROR EN EL QUE ESTAN.

    SALUDOS!!

  10. Ko-Barde mayo 17, 2010 en 2:10 pm

    Juan Pablo, gracias por una explicación tan detallada.

    Creo que la forma tan purista de explicarlo puede haber causado cierta confusión a los seguidores de java mas prácticos.

    Intentaré no liarlo mas y reitero mi agradecimiento por tu esfuerzo y los gráficos tan claros:

    En java todo son punteros, sólo que no hay necesidad de emplear la aritmética que hay en C para los mismos, en Java todo eso es automático.

    Pasemos lo que pasemos como parámetro a una función, esta recibe una copia del puntero del parámetro, es decir, que los punteros son pasados por valor. Esto para Java no es relevante.

    Cuando el parámetro que se pasa es un tipo primitivo (int, double, boolean) lo que se pasa es un puntero a una copia de su espacio de memoria, es decir, dentro de la función se trabaja la copia (el efecto es equivalente al de pasar el parámetro por valor).

    Cuando el parámetro es un objeto, se pasa una copia del puntero al objeto (sin clonar el espacio de memoria del objeto, que sería un derroche de la misma y de tiempo de CPU), es decir, dentro de la función se trabaja sobre el espacio de memoria del objeto, actuando sobre el contenido del objeto (el efecto es equivalente al de pasar el parámetro por referencia).

    Espero haber sido de ayuda

  11. Edgar agosto 3, 2011 en 4:05 am

    Hola a todos no tengo conocimientos tan profundos como ustedes y no voy a comentar sobre el tema tan interesante que estaban debatiendo, pero me interesó en la parte del comentario de “martin javier castellanos” que dice asi: “..que sucede en memoria al declarar una variable de tipo “clase” y que sucede en memoria cuando se le aplica la funcion “new” a ese objeto.”, si pudieran profundizar mas al respecto de como trabaja la memoria con las clases y sus instancias, o informarme sobre algun sitio.

    Salu2!!

  12. Java Tutorial septiembre 8, 2011 en 8:49 am

    De la web oficial de Oracle(antes Sun):
    http://download.oracle.com/javase/tutorial/java/javaOO/arguments.html (2 últimos apartados)

    Resumiendo:
    Tipos primitivos => paso por valor
    Objetos => paso por referencia.
    Hay que aclarar que dice, que lo que se pasa por valor es “la referencia del objeto (digamos que el puntero), se modifica el objeto y se devuelve ya modificado, pero no puedes reasignar(utilizar new) la variable del objeto (objeto =new Claseprueba() – ESTE CAMBIO DESAPARECERA AL TERMINAR EL METODO, apuntando de nuevo al objeto anterior)

    • rr7 octubre 15, 2011 en 7:22 pm

      Java Tutorial: vaya forma de tergiversar las cosas. Citado del enlace que tú mismo pones:

      “Reference data type parameters, such as objects, are also passed into methods BY VALUE.” (énfasis mío)

      Lo que dice el texto citado es que, como es sabido, los objetos en Java se manipulan únicamente a través de referencias. Son “tipos de datos de referencia”, que se pasan, como cualquier otro tipo en Java, por valor. Estás confundiendo “tipo de dato” con “forma en que ese dato se pasa a las funciones”.

      Así que los objetos se pasan por valor. Y ya lo demuestra muy bien escom.alex

  13. escom.alex octubre 5, 2011 en 5:17 pm

    Estoy de acuerdo con windoctor, Java hace paso por valor, es decir cuando se trabaja con objetos y se pasa la referencia a una función, se crea una copia (de la referencia) la cual también puede modificar el mismo objeto (dentro del ámbito de la función) com el ejemplo de RoHer, pero las referencias se mantiene intactas después de invocar a la función.Volvemos al mismo ejemplo, listo para compilar y probar.

    import java.lang.String;

    public class C
    {
    String s;

    C(){}

    C(String s){ this.s = s; }

    public String toString(){ return s;}

    public static void inter(C uno, C dos)
    {
    C temp = uno;
    uno = dos;
    dos = temp;
    }

    public static void main(String[] args)
    {
    C uno = new C(“UNO”);
    C dos = new C(“DOS”);
    System.out.println(“Antes de intercambiar”);
    System.out.println(“1.- ” + uno);
    System.out.println(“2.- ” + dos);
    C.inter(uno,dos);
    System.out.println(“Despues de intercambiar”);
    System.out.println(“1.- ” + uno);
    System.out.println(“2.- ” + dos);
    }
    }

    Como se puede apreciar aún cuando se intercambian las referencias dentro de la funcion “inter” la salida sigue siendo:

    Antes de intercambiar
    1.- UNO
    2.- DOS
    Despues de intercambiar
    1.- UNO
    2.- DOS

    Obvio, si dentro de la funcion inter (cuando los apuntadores temporales cambian de objeto referenciado) se modifica algún dato del objeto éste se verá afectado fuera de la función, ya que el objeto al que apuntan sigue siendo el mismo.

    • Francisco agosto 22, 2013 en 11:50 am

      En este ejemplo lo que estas haciendo es apuntar los parametros de la funcion inter a los objetos anteriormente creados, luego en la funcion reasignas los punteros dentro de la funcion, no los punteros de fuera de la funcion que siguen apuntando a los objetos igual que lo hacian antes.

      Esto lo unico que demuestra es que deberias estudiar algo mas las asignaciones de punteros y referencias.

  14. escom.alex octubre 5, 2011 en 5:27 pm

    Nota:
    Para aquellos que vayan a empezar a refutar esto, pueden modificar la función:

    public static void inter(C uno, C dos)
    {
    C temp = uno;
    uno = dos;
    dos = temp;
    System.out.println(“Dentro con referencias temporales”);
    System.out.println(“1.- ” + uno);
    System.out.println(“2.- ” + dos);
    }

    Salida:

    Antes de intercambiar
    1.- UNO
    2.- DOS
    Dentro de inter con referencias temporales
    1.- DOS
    2.- UNO
    Despues de intercambiar
    1.- UNO
    2.- DOS

    Touché !

  15. Jorge Chayan noviembre 11, 2011 en 2:49 am

    Amigo Autor Estas Es GRAN equivocado, no hay que llegar a los objetos… En Arreglos: Como es Que Al Aplicar Un Bubblesort A Un Arreglo Desde Un Metodo Externo, Modifica El Orden Del Arreglo Que Fue Pasado Como Parametro?? Lo Hace Por Referencia Amiguito!

  16. pepe@pepe.com noviembre 21, 2011 en 4:41 pm

    Sois todos unos ignorantes. Estoy de acuerdo con windoctor. ¿Es que nadie más sabe lo que es un paso por referencia? ¿O es que no habéis probado a ejecutar el código y ver lo que hace?. Los objetos también se pasan por valor, por mucho que digáis que lo que se pasa por valor es la dirección del puntero (ya no sería paso por valor sino por referencia) no va a ser así. Dejad de confundir a la gente.

    Estoy harto de tanto ignorante. Antes de publicar leer, informaros y probad, sobre todo probad lo que decís.

    En definitiva, gracias windoctor por hacer bien las cosas.

  17. Igor diciembre 15, 2011 en 11:01 pm

    ¿Cuántos de aquellos que afirman que los parámetros se pasan por referencia son en realidad programadores Java? Y no vale haber hecho un “Hello world!”…

    Pongo un enlace, para quienes entiendan inglés, a una página que es para quienes la conocen lo más parecido a la Biblia (versión Java) que se puede encontrar en Internet:

    http://stackoverflow.com/questions/1068760/can-i-pass-parameters-by-reference-in-java

    Por cierto, me hace gracia el comentario de escom.alex: “Dentro de inter con referencias temporales”. No está mal, se ha inventando las “referencias temporales” con tal de no dar la razón al autor y llamarlo con su nombre: paso por valor.

  18. Jazumaru abril 24, 2012 en 3:47 am

    import java.io.*;
    class prueba{

    public static void main(String args[]){
    int j[];
    j= new int[5];
    prueba.rt(j);

    for (int i=0;i<j.length;i++)
    System.out.println(j[i]);
    }

    public static void rt(int h[])
    {
    //en esta funcion se asignan los valores a la variable j que se declaro en main
    int e;
    for (int i=0;i<h.length;i++)
    {
    e=i*2;
    h[i]=e;
    }

    }
    }

    Alguien me podria explicar esto porque a mi me parece que pasa arreglos y objetos por referencia

  19. Raúl mayo 22, 2012 en 1:48 pm

    Ké follón tenéis! Madre mía!
    Lo primero ke yo diría es ke si no sois ingenieros en ciencias de la computación, por favor no habléis, ke lo único ke hacéis es liar a la gente.

    Todos sin kererlo estáis diciendo lo mismo. A ver, Java no es C++ (ya le gustaría tener el mismo potencial), no existen los punteros, con lo cual ya no se puede hablar de apuntadores a direcciones, aunke claro ke los maneja internamente. Entonces vamos al paso de parámetros. Os habéis cegado en el término en sí, y ya sabéis ke nuestro lenguaje es ambiguo, llamadle como keráis mientras sepáis lo ke hace. Pero al no haber punteros, yo personalmente no hablaría de paso por referencias, ya ke nunca podremos hacer algo del estilo: “function(type& var);”. Por otro lado si nuestro lenguaje es ambiguo (los ke han hecho IA saben a lo ke me refiero), hacedle caso al padre de Java “Gosling is generally credited with having invented the Java programming language in 1994″ ke dice en su libro “There is exactly one parameter passing mode in Java – pass by value – and that helps keep things simple.”

    Saludos a todos y gracias al autor por este post.

  20. el sentido comun es el menos comun de los sentidos... agosto 24, 2012 en 10:31 pm

    Señores por favor. Sea como sea los objetos pasados a una función (metodo) son pasados si o si como referencia en el sentido absoluto y práctico del concepto.

  21. Jerry octubre 11, 2012 en 10:00 pm

    Estos chavales me tienen confundido, al fin como es por valor o por parámetro?

  22. Ester octubre 19, 2012 en 9:23 am

    Java pasa todos los parámetros por VALOR. Otro tema es que el valor que tiene la variable cuando es un objeto sea la dirección de memoria del objeto (su referencia) y por tanto copia la referencia.
    La confusión se produce por el uso del concepto “paso por referencia”. Paso por referencia es cuando mando la dirección donde se aloja la variable, por tanto, un paso por referencia SIEMPRE implica que las modificaciones hechas dentro del método se mantienen fuera de el. Eso NO pasa en Java si asignamos un objeto a otro dentro de un método. Ejemplo:
    public class ParamObj {

    public static void main(String[] args) {
    String cadenaMain = “inicio”;
    System.out.println(” cadenaMain antes de llamada = ” + cadenaMain);
    metodo_1(cadenaMain);
    System.out.println(” cadenaMain despues de llamada = “+ cadenaMain);
    }

    public static void metodo_1(String variable) {
    String aux=”cadena_auxiliar”;
    variable= aux;
    System.out.println(” variable_metodo = ” + variable);
    }
    }
    Lo que ocurre tras las ejecución es:
    cadenaMain antes de llamada = inicio
    variable_metodo = cadena_auxiliar
    cadenaMain despues de llamada = inicio

    Por definición de paso por referencia, CadenaMain despúes de la ejecución debería tener el valor de cadena_auxiliar y no es así.

    • Gabi mayo 28, 2013 en 3:09 pm

      Pero Ester, si modificamos tú código y lo pasamos, además de con un String, que por aquí se ha dicho antes que, al igual que enteros y demás tipos básicos se pasa por valor, el resultado no es exactamente el mismo, me explico:

      public class cosa {

      public static void main(String[] args) {
      String cadenaMain = “inicio”;
      obj o = new obj();

      System.out.println(“cadenaMain antes de llamada = ” + cadenaMain + “, ” + o.v);
      metodo_1(cadenaMain, o);
      System.out.println(“cadenaMain despues de llamada = “+ cadenaMain + “, ” + o.v);
      }

      public static void metodo_1(String variable, obj a) {
      String aux=”cadena_auxiliar”;
      variable= aux;
      a.v = “Cambiada en el objeto!!”;
      System.out.println(“variable_metodo =” + variable);
      }
      }

      class obj {
      String v = “Antes!!”;
      }

      El resultado es que el objeto “o”, después de pasar por el metodo_1, tiene cambiado su valor, pero cadenaMain, no.

      • Ester mayo 28, 2013 en 7:22 pm

        objeto (la información que se guarda) es una dirección (referencia), y que lo que se copia es la dirección (es análogo a la idea de que una variable int guarda su valor, p.e el 452 y el 452 es lo que se copia). El String es un objeto más de Java. Te pongo un ejemplo con un vector:

        public class ParamVector {

        public static void main(String[] args) {
        int vector [] = {0,1,2,3};

        System.out.println(“La posicion 0 en el vector ANTES de la llamada es = ” + vector[0]);
        metodo(vector);
        System.out.println(“La posicion 0 en el vector DESPUES de la llamada es = ” + vector[0]);
        }

        public static void metodo(int [] vectorParam) {
        int [] vectorLocal={7,8,9,8};
        ** vectorParam = vectorLocal ;
        vectorParam[0]=32;

        System.out.println(“La posicion 0 en el vector DENTRO del metodo es = ” + vectorLocal[0]);
        System.out.println(“El valor de vectorParam es: “+vectorLocal);
        }
        }

        ** Al contener vectorParam una copia de vector (de la dirección al objeto), la asignación vectorParam = vectorLocal hace que vectorParam “apunte” (contenga) la dirección del vectorLocal, con lo que s la asignación vectorParam[0]=32; se hace sobre el objeto local y no afecta a vector cuando salimos del método. Si Java utilizase paso por referencia (tal y como se definen los lenguajes con paso por referencia) cualquier cambio en la variable pasada como parámetro se reflejaría al salir del método y como se puede comprobar, no es así.
        Saludos

        Ester

    • Gabi mayo 28, 2013 en 3:11 pm

      Ester, lo siento, había malinterpretado tu comentario, tienes razón en lo que dices, me pensaba que decías otra cosa incorrecta :)

      • Ester mayo 28, 2013 en 7:28 pm

        Espero que haya quedado un poco más claro con lo anterior :). Por cierto, el comentario anterior empezaba con la linea:
        Gabi, esa es la prueba de que se pasa todo por valor. Ten en cuenta que el “valor” de un…..

        es que había escrito todo en un editor y al copiarlo se me pasó copiar la primera linea.
        Saludos de nuevo

  23. ABM octubre 25, 2012 en 3:34 pm

    Hola a todos, en mi confusión me encontré con esta página, pensé que me enredaría más pero no fue así, excelente debate y gracias a todos por su participación.

  24. dante244 junio 9, 2013 en 3:53 pm

    En mi experiencia use varias instancias de una clase Animacion mas una auxiliar, algo como esto:
    Animacion a, b, c, aux;

    y si por ejemplo:

    aux=a;
    estaModificado?(aux); //Da false;

    modifico(aux);
    estaModificado?(aux); //Da true;

    y luego;

    aux=a;
    estaModificado?(aux); //Da true otra vez, osea en este caso me deberia dar false si las instancias estuviesen por valor pero es como si mofico aux, tambien se me modifica ‘a’ por lo que creo que estan por referencia. Crei que se pasaba todo por valor, este “problema” de mala interpretación me costo hacer mas código puesto que tenia que reiniciar la instancia ‘a’ a su estado inicial si quería que aux estuviese de nuevo con el ‘a’ inicial.
    Tambien tengo un libro en el que vi como se implementa una lista enlaza en java y si no hay pasaje por referencia entonces ese codigo no funcionaba, deberia probarlo haber si anda en serio.
    En realidad venia acá buscando respuestas así que no estoy muy seguro, solo cuento mi experiencia personal y doy mi razones para creer que hay pasajes por referencias en java.

  25. dofusyosi octubre 3, 2013 en 9:24 pm

    Saquen su propia conclusión con este sencillo ejemplo y diganme entonces si es por referencia o por valor.

    public static void main(String[] args) {
    //Paso por referencia o valor
    List lista = new ArrayList();
    lista.add(1);
    lista.add(2);
    System.out.println(“Antes: ” + lista);
    remover(lista);
    System.out.println(“Despues: ” + lista);
    }

    public static void remover(List valorReferencia){
    valorReferencia.remove(0);
    }

    Antes: [1, 2]
    Despues: [2]

    Entonces se hace por valor? o es acaso que se hace por referencia ?

    El paso de parametros de un Objecto lo hace por referencia. Y si aun tienen DUDAS solo hagan un debug, y se daran cuenta de todo.

    y para aquellos que ponen algun tipo de ejemplo como este….

    public class ParamVector {

    public static void main(String[] args) {
    int vector [] = {0,1,2,3};

    System.out.println(“La posicion 0 en el vector ANTES de la llamada es = ” + vector[0]);
    metodo(vector);
    System.out.println(“La posicion 0 en el vector DESPUES de la llamada es = ” + vector[0]);
    }

    public static void metodo(int [] vectorParam) {
    int [] vectorLocal={7,8,9,8};
    //vectorParam = vectorLocal ; –> Comenten Esta parte y veran
    // que el paso de parametros es por REFERENCIA
    vectorParam[0]=32;

    System.out.println(“La posicion 0 en el vector DENTRO del metodo es = ” + vectorLocal[0]);
    }
    }

    La posicion 0 en el vector ANTES de la llamada es = 0
    La posicion 0 en el vector DENTRO del metodo es = 7
    La posicion 0 en el vector DESPUES de la llamada es = 32

Deja un comentario

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

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 205 seguidores

%d personas les gusta esto: