Acessando objetos por referencias

12 respostas
E

Olá tudo bom?

Bom galera a minha dúvida agora é a seguinte, estou lendo a apostila da Caelum, estou no tópico: 4.7 Objetos são acessados por referencias.

[color=orange]A minha dúvida é a seguinte...
[/color]

eu instanciei:

Conta c1 = new Conta();
Conta c2 = c1;

Já que os dois objetos irão acessar o mesmo método, acredito que nao tem necessidade de fazer "Conta c2 = new Conta();
Mas ai que eu me enganei, gostaria de saber porque nao da certo? Já que o objeto é o mesmo :/

[size=18]VEJA Classe Programador:[/size]
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Caelum;

/**
 *
 * @author Eliseu
 */
public class Programa {
    public static void main(String[] args){
        Conta c1 = new Conta();
        Conta c2= new Conta();
        
        c1.dono = "Eliseu";
        c1.numero = 2323;
        c1.saldo = 500;
        c1.limite = 100;
        
        c2.dono = "José";
        c2.numero = 2121;
        c2.saldo = 400;
        c2.limite = 100;
        
        c1.transfere(c2,500);

           
        System.out.println("c1 saldo atual é de : "+c1.saldo);
        System.out.println("c2 saldo atual é de : "+c2.saldo);
        
    }
    
}
[size=18]VEJA Classe Conta:[/size]
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Caelum;

/**
 *
 * @author Eliseu
 */
public class Conta {
    int numero;
    String dono;
    double saldo;
    double limite;
    
    
    
    void transfere(Conta destino, double valor) {
    this.saldo = this.saldo - valor;
    destino.saldo = destino.saldo + valor;
    
    
    
    }
}
Porque não pode ser:
Conta c1 = new Conta();
Conta c2= c1;

12 Respostas

darklordkamui

não pode ser assim pois se vc por ventura modificar um atributo de um dos objetos isso ira refletir no outro…

ambos tem o mesmo endereço de memoria… se vc mandar imprimir com o System.out.println os Objetos verá que terão o mesmo endereço…

por isso vc tem que criar 2 referencias distintas para cada objeto ok?

exemplo se vc criar uma conta assim…

Conta c1 = new Conta();
Conta c2 = c1;

c2.setNome(“Blaa”);

e mandar imprimir tanto a conta 1 quanto a 2 teram o mesmo nome…

J

Não entendi qual a duvida.

Quando diz que c1 = c2 significa que c1 é o mesmo objeto que c2…
Se mudar c1 vai mudar c2 também…
Se são coisas diferentes é preciso instânciar um novo objeto.

O cuidado que tem que ter é quando você chama o mesmo objeto de dentro de métodos, em concorrência, pq ocorre do objeto ser copiado (e não acessado diretamente a referência) e não é garantido que modifique o mesmo objeto original (exceto se houver sincronização).

renanjp

Saudações companheiro…

Vou tentar lhe ajudar…

Há uma grandi diferença entre instancia(objeto) e referencia…

Instancia é o objeto já populado com os seus valores, ou seja, a ocorrencia “fisica” de tal modelo(classe)…

Referencia é algo que aponta para determinada instancia…

Por exemplo…

Pessoa p1, p2;
		
p1 = new Pessoa();
p2 = p1;
		
p2.nome = "Teste";
		
System.out.println(p1.nome);

Observe que a INSTANCIA é a mesma para as duas REFERENCIAS (p1,p2)
isto é um conceito muito importante em orientação a objetos…
Espero que vc tenha entendido tal…

qualqer duvida estou a disposição :slight_smile:

Att

lupearljam

Conta c1=new Conta(); ---->( Reserva um espaço em memória para este dado, c1 referencia este espaço)
Conta c2=c1; ---->( c1 ainda não foi instanciado ele não tem um espaço em memoria definido, logo c2 referencia o mesmo espaço de c1)

E

Muito obrigado a todos :smiley:

To reescrevendo o código no caderno pra min aprender, e surgiu outra dúvida:

Eu nao entendi porque em destino tem que ser do tipo conta?
mudei pra String mas nao deu certo! PQ tem que ser conta ali?
Oque esse conta faz? oque quer dizer?

void transfere(Conta destino, double valor) { this.saldo = this.saldo - valor; destino.saldo = destino.saldo + valor;

G

darklordkamui:
não pode ser assim pois se vc por ventura modificar um atributo de um dos objetos isso ira refletir no outro…

não existe “um” e “outro” objeto. só existe o objeto.

darklordkamui:

ambos tem o mesmo endereço de memoria…
…por isso vc tem que criar 2 referencias distintas para cada objeto ok?

criar o objeto (instancia), a referencia só aponta.

ta vendo como tem q ter mt cuidado com essas definicoes?

darklordkamui

GilsonNunes:
darklordkamui:
não pode ser assim pois se vc por ventura modificar um atributo de um dos objetos isso ira refletir no outro…

não existe “um” e “outro” objeto. só existe o objeto.

bom concordo com a primeira parte que voce falou… me expressei errado… MAS…

Porém na segunda ta correto a afirmação que fiz, pois quando eu dou um new o java por baixo dos panos vai la na memoria cria o objeto e então gera a referencia dele e armazena na variavel c1, ou vc acha que eu crio objeto e pronto ta feito?

S

É simples meu caro, a variavel de referencia destino aponta para um objeto do tipo conta, que no caso, a conta será passado como parametro para o metodo transfere.

Dentro do metodo, o saldo da conta que a variavel destino está apontando receberá um acrecimo (conforme a linha 3).

Seria a mesma coisa que:

public static void main(String[] args) {
		Conta c1 = new Conta();
		Conta c2 = new Conta();

		c1.dono = "Eliseu";
		c1.numero = 2323;
		c1.saldo = 500;
		c1.limite = 100;

		c2.dono = "José";
		c2.numero = 2121;
		c2.saldo = 400;
		c2.limite = 100;

		
		double valor = 500;
		// c1.transfere(c2,500);
		
		{
			c1.saldo = c1.saldo - valor;  
			c2.saldo = c2.saldo + valor;
		}
		
		System.out.println("c1 saldo atual é de : " + c1.saldo);
		System.out.println("c2 saldo atual é de : " + c2.saldo);

	}
E

Galera nao to conseguindo entedender isso, alguem poderia exclarecer essa dúvida fazendo favor!!!

Eu nao entendi porque em destino tem que ser do tipo conta?
mudei pra String mas nao deu certo! PQ tem que ser conta ali?
Oque esse conta faz? oque quer dizer?

void transfere(Conta destino, double valor) { this.saldo = this.saldo - valor; destino.saldo = destino.saldo + valor;

S

eliseumixmt:
Galera nao to conseguindo entedender isso, alguem poderia exclarecer essa dúvida fazendo favor!!!

Eu nao entendi porque em destino tem que ser do tipo conta?
mudei pra String mas nao deu certo! PQ tem que ser conta ali?
Oque esse conta faz? oque quer dizer?

void transfere(Conta destino, double valor) { this.saldo = this.saldo - valor; destino.saldo = destino.saldo + valor;

Acabei de responder a sua pergunta.

DavidUser

O java foi construído e baseado no C++,
no C++ temos conceito de objetos, referencias e ponteiros,
objetos como no C++ não existem no java,
referencias como no C++ não existem no java,
ponteiros são a única coisa que o java usa.

Um ponteiro nada mais é que um espaço em memória que guarda um endereço de memória,

int numero;

Cria uma variavel que guarda numeros inteiros,
Variável, espaço reservado na memória que tem um nome e tipo,
Tipo, define como tratar um conjunto de bits (zeros e um agrupados, modo como o computador armazena dados) para facilitar sua utilização.
No codigo citado acima o tipo é int e o nome dado ao espaço na memória é numero.

Representando graficamente:

Memória (vazia):
0_________1________2________3__________4__________5_
||||||______

Memória (com variavel):

____numero_______________________5__________6
___[<conteudo da variavel>]||

cada marcação da memória tem um endereço
este nome numero na realidade e apenas uma representação do próprio endereço.

quando começamos a falar de objeto a coisa muda um pouco de rumo pois é uma extensão do que já temos, uma extensão das variáveis fundamentais

Na linha:

Conta c1;

criamos implicitamente uma variavel inteira como a citada anteriormente, mas agora guardando como [u]conteudo/u o endereço de memoria de uma outra variavel sem nome

___[color=red]c1[/color]5__________6
_________________[[color=red]<endereco de variavel>[/color]]
|
____|

A palavra chave new aloca um espaço na memória e retorna o endereço onde começa o espaço alocado:

new Conta();

_____c1____________________________5__________6
_________________[<endereco de variavel>]|[[color=red]<alocado com tamanho para guardar uma Conta>[/color]]

nesse caso o comando acima alocaria um espaco iniciando no endereco 6 e retornaria o numero 6 que é o endereço de inicio do espaço alocado.

Quando fazemos:

Conta c1 = new Conta();

Estamos alocando o espaco na memoria e guardando seu endereco no conteudo de c1, assim podemos trabalhar diretamente em c1 modificando o conteudo do espaco cujo endereco esta guardado no seu conteudo ( :roll: ficou pesado mas lendo devagar você entente)

graficamente:
c1_____________________________5[color=red]6[/color]_____
_________________[ [color=red]6[/color] . . . . . . . . . . . . . . . . . . ]|[<alocado com tamanho para guardar uma Conta>]

Mas quando fazemos:

Conta c2 = c1;

estamos apenas guardando em c2 o mesmo endereço guardado em c1, então ambos acabam trabalhando com o mesmo espaço( Objeto em si ).

E

vlw muito obrigado a todos!

Criado 10 de julho de 2012
Ultima resposta 11 de jul. de 2012
Respostas 12
Participantes 8