Questão sobre referencia de objeto

galera, estou estudando e fiquei em duvida na seguinte questao de um simulado:

class GFC301 {
  private String name;
  public GFC301(String name) {this.name = name;}
  public void setName(String name) {this.name = name;}
  public String getName() {return name;}
  public static void m1(GFC301 r1, GFC301 r2) {
    r1.setName("Bird");
    r2 = r1;
  }
  public static void main (String[] args) {
    GFC301 pet1 = new GFC301("Dog");
    GFC301 pet2 = new GFC301("Cat");
    m1(pet1,pet2);
    System.out.println(pet1.getName() + "," + pet2.getName());
  }
}

A resposta é: Bird, Cat

Porque o objeto pet2 não foi alterado ???

valeu

Java não usa passagem de argumento pro referência, mas sim por valor.
No método m1 vc trocou a referência da variável local ao método e isso não se reflete pra fora.

Isso me lembrou uma discussao que tivemos no servico ha quase 1 ano atras, o experiente desenvolvedor Senior disse pra nos:

Claro que foi simplesmente engracado quando mostramos pra ele que era o contrario e ele todo brabo disse que nao ia comer, e olha que eu jah estava comecando a imprimir ao menos o codigo de uma classe (tah certo, com 3.000 linhas, mas uma classe soh) como entrada… hehe

[quote=danieldestro]Java não usa passagem de argumento pro referência, mas sim por valor.
No método m1 vc trocou a referência da variável local ao método e isso não se reflete pra fora.[/quote]

Mas no caso, r1 reflitiu para fora…
r2 não refletiu…

Quanto “r2 = r1” é executado, r2 não recebe o valor, mas sim a referência de r1
ou seja, r1 e r2 estão apontando para o mesmo objeto em memória, tanto que se alterarmos o método para:

public static void m1(TesteReferenciaObjetos r1, TesteReferenciaObjetos r2) {
     r1.setName("Bird");
     r2 = r1;
     r2.setName("teste");
   }

r1 e r2 terao “teste” como nome, dentro deste método e r1 fora.

Vendo que r1 mudou o nome fora do método (quando acessado pelo método main), r1 foi passado por referência então… Consequentemente r2 tb…
Mas porque, quando digo para r2 “apontar” para r1, no método main isso não reflete?!

Não consegui pegar a lógica… :roll:

Quando você passa um objeto como argumento a um método, é passada uma cópia da referência ao objeto.

Na linguagem C++, por exemplo, você pode passar o próprio endereço da referência, por isso ele se altera dentro do método.

Voltando por Java.

Quando você altera a referência de um argumento, ele não reflete fora, pois aquele argumento tinha uma cópia para a refência a um objeto referenciado também fora do método, e aquela referência externa permanece imutável.

Quando você altera algum atributo de um objeto passado como argumento, você está mudando o conteúdo interno daquele objeto, por isso reflete fora,. do método.

Espero que, apesar de confuso, eu tenha sido “claro”… hehheehhee

Eu não estava ligando o atributo do objeto com a referência do objeto…

Quando muda o valor de algum atributo você está mudando internamente isso, dentro da mesma referência, mas quando você muda a referência do objeto, desacopla o mesmo da referência passada por parâmentro ao método… ou seja, no primeiro método (de chamada) a referencia continua o mesmo, mas no segundo método a referencia para r2 é outra agora…

Isso? :smiley:

É para isso também que existe o encapsulamento!

Olá a todos

O que ocorre é que variáveis primitivas são passadas por valor e objetos são passados por referência.
Acredito que seja a definição mais simples.

Errado amigo.

É tudo passado por VALOR.

Os tipos primitivos são passadas as cópias do valor.

Os objetos são passadas as cópias da referência.

Olá a todos, boa noite,

Tem razão, desculpe. Não tinha entendido ainda perfeitamente. Fui estudar para não ajudar errado novamente.
Agora consegui entender, existe um exemplo muito claro no CoreJava 7 edicao, para mostrar que realmente só ocorrem passagens por valor. alias pagina 69 e 70.

public static void swap( Employee x, Employee y ) {

// nao funciona

   Employee temp = x;
   x = y;
   y = temp;

}

se por acaso :

  Employee a = new Employee("Joao");
  Employee b = new Employee("Maria");

  swap( a, b );

os parametros x e y do metodo swap sao copias das referencias, ocorre a troca entre elas “de referencia”, porém a e b continuam a manter suas referencias inicias.

acho que agora posso dizer que Java passa tudo por valor.

[quote=domingosbernardo]Olá a todos, boa noite,

Tem razão, desculpe. Não tinha entendido ainda perfeitamente. Fui estudar para não ajudar errado novamente.
[/quote]

Se preocupe não cara… erros acontecem =o)

Até pouco tempo eu pensava do mesmo modo, mas só por ter lido em algum canto, alguma tradução mal feita =o)

Mas pensando direitinho vc iria chegar a essa conclusão sozinho. kkkk

É isso ai o forum serve pra isso.