Press enter to see results or esc to cancel.

Passagem por valor em Java – Parte 2 de 2

Neste post, continuaremos a conversa iniciada na publicação anterior. Agora, as coisas ficam um bem mais interessantes.

Falaremos sobre controles remoto e televisores. Também veremos onde é que a passagem por valor dos tipos de referência entram nessa história. Vamos lá?

Tipos de referência e copos com controle remoto

As classes são tipos de referência, incluindo tanto as classes pré-definidas na linguagem Java quanto as que nós programadores criamos. O copo de uma variável de referência é um pouco mais interessante dos copos das variáveis primitivas. Observe o seguinte código:

Pessoa p = new Pessoa();

Os componentes dessa instrução podem ser descritos da seguinte forma:

  • Pessoa é o tipo da variável de referência.

  • p é a variável de referência (ou o nosso copo).

  • new é o operador usado para criar um novo objeto.

  • Pessoa() é o objeto ao qual a variável p faz a referência.

O que a variável p guarda é uma referência para o objeto Pessoa criado. É como se ela guardasse um controle remoto para controlar o objeto.

3

Repare que o controle remoto não tem nome, mas o copo sim. É por meio do nome do copo que nós podemos controlar o objeto Pessoa criado.

Em Java nós podemos criar uma variável de referência que não controla objeto algum da seguinte forma:

Pessoa p;

4

O copo p guarda um controle remoto que ainda não foi “programado” para controlar um objeto Pessoa. Portanto, o valor de p é null.

Tipos de referência e a passagem por valor

Como fazemos para passar uma variável de referência para um método ou outra variável de referência? A regra é a mesma das variáveis primitivas. Tudo na linguagem Java é passado por valor. Sempre.

Considere as seguintes instruções:

Televisao tv1 = new Televisao();
Televisao tv2 = tv1;
tv1 = null;
tv1 = new Televisao();
tv2 = tv1;

A sequência dos eventos está ilustrada abaixo:

Televisao tv1 = new Televisao();
Televisao tv1 = new Televisao();

A linha 1 cria um copo chamado tv1, ele guarda um controle remoto que está programado para controlar o objeto Televisao criado. Ou seja, é a declaração de uma variável de referência chamada de tv1 que guarda a referência para o objeto Televisao criado.

Televisao tv2 = tv1;
Televisao tv2 = tv1;

A linha 2 copia o controle remoto do copo tv1, que controla o objeto Televisao, e coloca essa cópia dentro do copo tv2. Neste momento temos duas variáveis de referência diferentes que fazem referência ao mesmo objeto Televisao.

tv1 = null;
tv1 = null;

A linha 3 coloca null no controle remoto do copo tv1. Agora, esse controle remoto está desprogramado e não consegue mais se comunicar com o objeto Televisao.

Observe que o controle remoto do copo tv2 ainda está programado para se comunicar com o objeto Televisao. Esse objeto e o copo tv2 não foram alterados.

Lembre-se que são dois copos e dois controles remotos diferentes. Uma alteração em um controle remoto não vai afetar o outro.

tv1 = new Televisao();
tv1 = new Televisao();

A linha 4 cria um novo objeto do tipo Televisao e programa o controle remoto do copo tv1 para fazer o controle dele.

Repare que neste momento nós temos dois objetos do tipo Televisao diferentes e que o copo tv2, controle remoto do copo tv2 e o Objeto Televisao não foram alterados.

tv2 = tv1;
tv2 = tv1;

O controle remoto do copo tv1 já estava programado para controlar o Novo Objeto Televisao. A linha 5 faz uma cópia desse controle remoto e coloca dentro do copo tv2. Portanto o controle remoto que foi colocado dentro do copo tv2 também controla o Novo Objeto Televisao.

A partir desse momento, não temos nenhum controle remoto programado para controlar o Objeto Televisao. Agora ele é um objeto sem referências.

 


Televisao tv2 = tv1;
Errado! Correto!
Coloque o copo tv1 dentro do copo tv2 Faça uma cópia do controle remoto contido dentro do copo tv1 e coloque essa cópia dentro do copo tv2

Tipos de referência e métodos

Qual é a saída do código abaixo?

public static Televisao metodo1(Televisao tv) {
	tv = new Televisao();
	tv.marca = "Sony";
	return tv;
}

public static void main(String args[]) {
	Televisao tv1 = new Televisao();
	tv1.marca = "LG";
	tv1 = metodo1(tv1);
	System.out.println(tv1.marca);
}

Na primeira linha do método main é criada uma variável de referência chamada tv1. Ela guarda a referência para um objeto Televisao criado nessa mesma linha.

Na segunda linha é atribuido o valor “LG” para o membro marca do objeto Televisao referenciado pela variável de instância tv1.

Na terceira linha o metodo1 é chamado e é passado como argumento a variável de referência tv1. Neste momento é feita uma cópia do valor da referência da tv1, ou seja, é feita uma cópia do controle remoto da tv1. Essa cópia é colocada dentro da variável, ou copo, tv do metodo1.

Ocorreu uma passagem por valor.

Perceba que tanto tv1 quanto TV referenciam o mesmo objeto criado na primeira linha do método main, mas logo na primeira linha do método metodo1 ocorre a criação de um novo objeto. O controle remoto desse novo objeto é colocado na variável de referência tv. Portanto, agora existem 2 objetos. Um objeto é referenciado por tv1 e outro objeto é referenciado por tv.

Na linha 2 do método metodo1, o objeto referenciado pela variável de referência tv tem o valor “Sony” colocado em seu membro marca.

Na linha 3 do método main, ocorre a atribuição do retorno do método metodo1 para a variável de referência tv1. O que o método metodo1 retorna não é nada mais que uma referência, ou seja, a cópia de um controle remoto que será colocado dentro do copo tv1.

A referência que a variável tv1 guarda, agora aponta para o objeto que foi criado dentro do método metodo1. Portanto o que aparece na tela na execução da linha 4 do método main é “Sony”.

As imagens a seguir mostram passo a passo a criação e manipulação das variáveis de referência e objetos:

Televisao tv1 = new Televisao();
Televisao tv1 = new Televisao();
metodo1(tv1);
metodo1(tv1);
tv = new Televisao();
tv = new Televisao();
tv1 = metodo1(tv1);
tv1 = metodo1(tv1);
Share on FacebookTweet about this on TwitterShare on Google+Share on LinkedInEmail this to someone
Comments

1 Comment

Rui

Muito bem explicado.


Leave a Comment