27

¿Cuál es la diferencia entre estos 2 códigos:pase de Java por referencia

Código A:

Foo myFoo; 
myFoo = createfoo(); 

donde

public Foo createFoo() 
{ 
    Foo foo = new Foo(); 
    return foo; 
} 

vs. Código B:

Foo myFoo; 
createFoo(myFoo); 

public void createFoo(Foo foo) 
{ 
    Foo f = new Foo(); 
    foo = f; 
} 

¿Hay alguna diferencia entre estos 2 códigos?

+7

No hay "pase por referencia" allí. Pasa por valor, y el valor es una referencia. El código B no compila, y si lo hiciera no cambiaría myFoo. – harold

Respuesta

165

Java siempre pasa los argumentos por valor NO por referencia.


Me explico esto a través de un example:

public class Main 
{ 
    public static void main(String[] args) 
    { 
      Foo f = new Foo("f"); 
      changeReference(f); // It won't change the reference! 
      modifyReference(f); // It will modify the object that the reference variable "f" refers to! 
    } 
    public static void changeReference(Foo a) 
    { 
      Foo b = new Foo("b"); 
      a = b; 
    } 
    public static void modifyReference(Foo c) 
    { 
      c.setAttribute("c"); 
    } 
} 

Voy a explicar esto en pasos:

  1. Declarar una referencia con nombre f de tipo Foo y asignarlo a un nuevo objeto del tipo Foo con un atributo "f".

    Foo f = new Foo("f"); 
    

    enter image description here

  2. Desde el lado del método, una referencia de tipo Foo con un nombre a se declara y se asigna inicialmente a null.

    public static void changeReference(Foo a) 
    

    enter image description here

  3. Como se llama al método changeReference, se le asignará la referencia a al objeto que se pasa como argumento.

    changeReference(f); 
    

    enter image description here

  4. Declarar una referencia con nombre b de tipo Foo y asignarlo a un nuevo objeto de tipo Foo con un atributo "b".

    Foo b = new Foo("b"); 
    

    enter image description here

  5. a = b se re-asignación de la referencia a NO f al objeto cuya su atributo es "b".

    enter image description here


  6. Como se llama a modifyReference(Foo c) método, se crea una referencia c y asignado al objeto con el atributo "f".

    enter image description here

  7. c.setAttribute("c"); cambiará el atributo del objeto que la referencia en c puntos a la misma, y ​​es mismo objeto que la referencia en f puntos a la misma.

    enter image description here

espero que entienda ahora cómo pasar objetos como argumentos trabaja en Java :)

+15

¡EXCELENTE explicación! ¡Me siento iluminado! – delita

+10

Holy cow. Esto se ha preguntado y respondido muchas veces, pero esta es la solución más elaborada y artística que he visto. ¡Bravo! – duffymo

+0

¿Puedes contrastar qué aspecto tendría "pasar por referencia"? Lo que tiene sentido para mí es con "pasar por valor", es pasar la dirección de memoria del objeto referido por f. En ** changeReference **, ** a ** es una nueva variable que hace referencia a la misma dirección de memoria, cambiar ** a ** 's value (o referirse a la dirección de memoria) solo cambia lo que ** a ** apunta a y no ** f **. Si fuera "pase por referencia" ** f ** se pasaría así que ** a = f **, cambiar el valor de ** a ** (o la dirección de memoria referenciada) cambiaría ** f ** –

8

Dado que Java es estrictamente "paso por valor" e incluso las referencias a los objetos se pasan por valor, el segundo código no funcionará como se esperaba. Consulte la sección "Relacionados" a la derecha para numerosas discusiones de sobre esto.

2

Piense en los parámetros del método como sus propias variables declaraciones. Si se va a sustituir la llamada al método con un solo bloque de código, se ve así:

Foo myFoo; 
{      //Method call starts here 
    Foo foo; 
    foo = myFoo; 
    Foo f = new Foo(); 
    foo = f; 
}      //Method call ends here 

Incluso si el parámetro de método tiene el mismo nombre que otra variable, el parámetro del método sigue siendo su propio, único de referencia que solo el método conoce. Eso es lo mismo que dice Eng.Fouad arriba.

1

Otro punto importante que debes saber es el tipo de objeto que pasas al método. si es un objeto mutable o un objeto inmutable. Si pasa un objeto inmutable como String, creará otra copia y realizará la modificación. Los cambios no se reflejan en su copia original.

+0

No, no hay ningún concepto de "mutable" o "inmutable" en el idioma. Por lo tanto, no hay diferencia en cómo se pasan. "Los cambios no se reflejan en su copia original". Un objeto inmutable, por definición, es uno que no tiene un método para "cambiar", por lo que esta afirmación no tiene sentido. – newacct

Cuestiones relacionadas