Java pass por referência

Qual é a diferença entre esses dois códigos:

Código A:

Foo myFoo; myFoo = createfoo(); 

Onde

 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; } 

Existem diferenças entre esses dois códigos?

Java sempre passa argumentos por valor NOT por referência.


Deixe-me explicar isso através de um exemplo :

 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"); } } 

Vou explicar isso em etapas:

  1. Declarar uma referência chamada f do tipo Foo e atribuí-la a um novo object do tipo Foo com um atributo "f" .

     Foo f = new Foo("f"); 

    insira a descrição da imagem aqui

  2. Do lado do método, uma referência do tipo Foo com um nome a é declarada e inicialmente atribuída a null .

     public static void changeReference(Foo a) 

    insira a descrição da imagem aqui

  3. Conforme você chama o método changeReference , a referência a será atribuída ao object que é passado como um argumento.

     changeReference(f); 

    insira a descrição da imagem aqui

  4. Declarar uma referência chamada b do tipo Foo e atribuí-la a um novo object do tipo Foo com um atributo "b" .

     Foo b = new Foo("b"); 

    insira a descrição da imagem aqui

  5. a = b está reatribuindo a referência a NOT f ao object cujo atributo é "b" .

    insira a descrição da imagem aqui


  6. Conforme você chama o modifyReference(Foo c) , uma referência c é criada e atribuída ao object com o atributo "f" .

    insira a descrição da imagem aqui

  7. c.setAttribute("c"); mudará o atributo do object que a referência c aponta para ele, e é o mesmo object que a referência f aponta para ele.

    insira a descrição da imagem aqui

Espero que você entenda como a passagem de objects como argumentos funciona em Java 🙂

Como Java é estritamente “passar por valor” e até mesmo referências a objects são passadas por valor, o segundo código não funcionará como esperado. Veja a seção “Related” à direita para várias discussões sobre isso.

Pense nos parâmetros do método como suas próprias declarações de variables. Se você fosse replace a chamada de método por um único bloco de código, seria assim:

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

Mesmo se o parâmetro do método tiver o mesmo nome que outra variável, o parâmetro do método ainda é sua própria referência exclusiva que somente o método conhece. É a mesma coisa que o Eng.Fouad diz acima.

Outro ponto importante que você deve saber é o tipo de object que você passa para o método. se é um object mutável ou um object imutável. Se você passar um object imutável como String, ele criará uma outra cópia e fará a modificação. As alterações não são refletidas na sua cópia original.