[Solucionado]Paso de parámetros por referencia

Iniciado por PabloPbl, 21 Octubre 2015, 06:07 AM

0 Miembros y 1 Visitante están viendo este tema.

PabloPbl

Estoy muy enredado con esto del paso de parámetros en Java, si es por valor o por referencia  :-\

Estuve leyendo un par de artículos por internet y según dicen que los pasos por parámetros en Java, son por valor y no por referencia.

Pero lo que no me entra en la cabeza, es cuando le paso un objeto como parámetro a un método, este supuestamente si fuera por valor, el método debería tomar una copia del objeto, pero no al contrario, el método efectúa los cambios en el objeto original que le pase  :-\ , Varios artículos que he leído afirman que Java es 100% paso de parámetros por valor, pero cuando se trata de pasar objetos por parámetros, los métodos hacen los cambios en el objeto original que le pase, es decir que no hacen una copia de dicho objeto, al contrario con los datos primitivos(int, long, short, String) que si lo hace.

¿Entonces Java es por valor y por referencia?  :-\
Java es raro :¬¬ es compilado e interpretado también  :-[ jaja pero eso no viene al caso.

¿Alguien sabe por que sucede esto, o que entendí mal?  :-\

Muchas gracias desde ya.

kondrag_X1

JAJAJAJA ami me paso lo mismo hace tiempo en al universidad me enseñaron que en java se pasaba por valor y punto.

pero más tarde trabajando de freelance me di cuenta que con los objetos no pasaba y buscando buscando llegué a la misma conclusión.

En java se pasan por valor los tipos básicos como int,byte,short,long etc... pero los objetos si se pasan por referencia.

échale un ojo.
https://cafelojano.wordpress.com/2007/06/27/en-java-el-paso-de-parametros-es-por-valor/

DarK_FirefoX

Cita de: DarK_FirefoX en 25 Julio 2015, 17:23 PM
En java se pasa todo por valor, lo que hay que entender es que pasa los objetos por referencia, y esas referencias se pasan por valor.

Lee esto: http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value

Salu2s

PabloPbl

Muchas gracias por sus respuestas  ;-)

He leído ambos artículos, y también he llegado a la misma conclusión que kondrag_X1  :-\
No hay caso de que entienda esto:

CitarEn java se pasa todo por valor, lo que hay que entender es que pasa los objetos por referencia, y esas referencias se pasan por valor.

He leído el articulo, el que me paso DarK_FirefoX, pero no logre entenderlo  :huh:

Entonces esto seria lo mismo que por referencia?  :-\

He hecho mas pruebas para indagar un poco mas y esto es lo que paso:

Tengo 3 clases:

Clase con el main
Código (java) [Seleccionar]

public class PruebaParametros {
   
   public static void main(String[] args) {
       Perro perro = new Perro("Boby");
       System.out.println(perro.nombre);
       
       EditorPerro editorPerro = new EditorPerro(perro);
       System.out.println(perro.nombre);
   }
}



Clase perro
Código (java) [Seleccionar]

public class Perro {

   String nombre;
   
   public Perro(String nombre) {
       this.nombre = nombre;
   }
}



Clase que modifica los atributos del perro, en este caso solo el nombre (EditorPerro)
Código (java) [Seleccionar]

public class EditorPerro {
   private Perro perro;
   
   public EditorPerro(Perro perro) {
       this.perro = perro;
       this.perro.nombre = "Nombre cambiado";
   }
}



En el main instancio un objeto de la clase perro y le paso por parámetro el nombre del perro, y luego imprimo el valor de la variable "nombre" del objeto perro para corroborar el cambio. Hasta ahí todo perfecto.

Ahora instancio un objeto de la clase EditorPerro y le paso como parámetro la instancia del objeto perro anteriormente creado, y lo que hace este método de la clase EditorPerro, es:
Hace que la variable "perro" de clase tome el valor de lo que le pase por parámetro, y aquí viene la parte extraña  :-\ , lo que hago es modificar el valor de la variable "nombre" PERO de la clase, la que esta como privada, y lo que hago es cambiar el nombre a "Nombre cambiado", como se puede ver en el código.

Ahora vuelvo al main, e imprimo nuevamente la variable nombre, del objeto Perro, y adivinen que?  :-\ :-\ :-\
Tomo el valor "nombre cambiado"   :P

Osea que cuando el método modifico el objeto de la clase, me modifico también el original y eso que era otro objeto, y que si fuera paso de parámetros por valor, no debería hacer eso.

Debería resignarme a pensar de esta manera? tendré problemas en un futuro si sigo pensando así?  :-\

PabloPbl

#4
Después de investigar bastante, he logrado entender por fin el paso de parámetros en Java  ;-)
Bueno al menos eso creo yo  :P

Intentare explicar lo que entendí:

En muchos artículos leía esto:

En java se pasa todo por valor, lo que hay que entender es que pasa los objetos por referencia, y esas referencias se pasan por valor.

Pero nunca lograba entenderlo del todo. Hasta ahora:

Esta frase significa que los objetos que se pasan por parámetros se pasan por referencia, pero por un valor, y no el objeto en tal como se haría en C/C++. Ese valor es como una especie de apuntador a la memoria en donde se encuentra dicho objeto.

Muestro un ejemplo:

Cuando nosotros creamos un objeto en Java:

Código (java) [Seleccionar]
Perro perro1 = new Perro("Bobby");

Estamos reservando espacio en memoria para un nuevo objeto, y lo que hacemos es apuntar con la variable perro1 a ese objeto que acabamos de crear.
Podemos tener mas de 1 variable apuntando a un mismo objeto, por ejemplo:

Código (java) [Seleccionar]

Perro perro1 = new Perro("Bobby");
Perro perro2 = perro1;


Como ven las variables perro1, y perro2 están apuntando al mismo objeto. Ahora bien, que pasaría si hago lo siguiente:

Código (java) [Seleccionar]

Perro perro1 = new Perro("Bobby");
Perro perro2 = perro1;

perro1 = new Perro("Lobito");


¿Que pasaría con la variable perro2? Pues nada, la variable perro2, seguiría estando igual, seguiría apuntando al mismo objeto de siempre, lo único que paso fue que la variable perro1 esta apuntando a otro objeto nuevo, eso es lo único que paso.

Ahora otro ejemplo pero con métodos, que es lo que me confundía, pero teniendo claro la información anterior, logre entender esto de los pasos por parámetros ;D  :

Tenemos una clase común y corriente, con sus respectivos get y set:

Código (java) [Seleccionar]
public class Perro {
    private name;

    public Perro(String name) {
         this.name = name;
    }

    public void setName(String name) {
         this.name = name;
    }

    public String getName() {
         return this.name;
    }
}


Y tenemos la clase Main:

Código (java) [Seleccionar]
public class Main {

    pubic Main() {
         Perro perro1 = new Perro("Bobby");
         modificar(perro);
    }    

    public void modificar(Perro perro) {
         Perro perro2 = new Perro();
         perro = perro2;
    }

    public static void main(String[] args) {
         new Main();
    }
}



Bien, en el constructor de la clase Main, creamos un objeto y la variable que lo esta apuntando es perro1.
Después llamamos al método modificar y le pasamos como parámetro el objeto perro1, PERO... en realidad no le estamos pasando el objeto, si no que le estamos pasando la referencia como un valor a ese objeto, por lo que en el método modificar, la variable perro también esta apuntando al mismo objeto.
Dentro del método modificar creamos otro objeto perro y la variable que lo esta apuntando es perro2, ahora prestemos atención en esta parte:

Cuando hacemos lo siguiente, ¿que creen que pasara?:
Código (java) [Seleccionar]
perro = perro2;

Lo que pasara es que la variable perro solo apuntara a lo mismo que esta apuntando perro2. En ningún momento estaríamos modificando la variable perro1 que anteriormente creamos. :laugh:

ADVERTENCIA: No estoy 100% seguro de que esta idea sea 100% certera, por favor corrijanme si me equivoco.
Agradecería si me dijeran si mi idea es correcta, así me quito una carga muy pesada de encima  :-\

Un articulo que me ayudo a entender esto: http://www.iteramos.com/pregunta/1043/java-es-por-referencia-o-paso-por-valor

Espero que sirva de ayuda, un saludo  ;)