Referências de Memória

Galera estou com outra dúvida:

Suponhamos que eu tenha o seguinte código:


public class Animal{
    String nome;
    int size, age;

}

public class Testador{

    public static void main (String [] args){

        Animal a=new Animal();

    
    }


}

Sabemos que variáveis em geral recebem “rótulos” para referenciar uma posição na memória, como por exemplo a variável int size, size seria o “rótulo”.
Quando por exemplo formos acessar essa variável a partir da classe Testador, devemos usar a sintaxe a.size, no caso minha dúvida seria referente a como é organizado isso, seriam duas referencias para apenas uma variável? Como uma só variável de referencia como a variável Animal a, consegue referenciar tantas variáveis? Não sei se consegui ser claro.

Obrigado

Bem, cara o a é uma instância da classe Animal estou certo? Gosto de fazer analogia de uma classe com uma receita de bolo:
Você possui os ingredientes(variáveis), e as ações (bater as claras em neve, colocar cobertura).
Logo um bolo pode sim ter o número de ingredientes que quiser(variáveis) e também o número de ações que quiser.
Na maioria dos casos nós só alteramos os nossos ingredientes(ovos, manteiga) através de nossas ações(adicionar mais açúcar, ou cobertura),
isso vai garantir que, dependendo da sua implementação, os dados não fiquem inconsistentes resultando em um bolo mal feito ou com gosto ruim.

Aconselho uma visita aocapítulo 4 da apostila de Orientação a Objetos da Caelum: http://www.caelum.com.br/download/caelum-java-objetos-fj11.pdf
Espero ter ajudado.

[quote=SamuelMedeiros][quote=dntalemao]
Como uma só variável de referencia como a variável Animal a, consegue referenciar tantas variáveis? Não sei se consegui ser claro.
[/quote]

Bem, cara o a é uma instância da classe Animal estou certo? Gosto de fazer analogia de uma classe com uma receita de bolo:
Você possui os ingredientes(variáveis), e as ações (bater as claras em neve, colocar cobertura).
Logo um bolo pode sim ter o número de ingredientes que quiser(variáveis) e também o número de ações que quiser.
Na maioria dos casos nós só alteramos os nossos ingredientes(ovos, manteiga) através de nossas ações(adicionar mais açúcar, ou cobertura),
isso vai garantir que, dependendo da sua implementação, os dados não fiquem inconsistentes resultando em um bolo mal feito ou com gosto ruim.

Aconselho uma visita aocapítulo 4 da apostila de Orientação a Objetos da Caelum: http://www.caelum.com.br/download/caelum-java-objetos-fj11.pdf
Espero ter ajudado.[/quote]

Samuel, o paradigma OO eu até já compreendi, eu gostaria de saber realmente como funciona por baixo dos panos. Mas agradeço muito a ajuda cara! valeuu

ele guarda as Referências para os Objetos em Arvores

siga meu exemplo:

endereço do objeto no Pool de Objetos: Animal a = 154125
quando você digitar a, ele vai localizar o endereço 154125, então ele carrega seus atributos e métodos… se o atributo for um valor ele estará gravado junto com o objeto, caso seja uma referência ex Animal femea, ele guardará a referência: objetoReferênciado = 125874, este objeto femea estará guardado em outro local no Pool de Objetos.

um objeto guarda ponteiros para os métodos que ficam em outro local.

agora um exemplo que talves te ajude a clarear:

[code]public class Pessoa{

int id;

Pessoa conhecido;

}[/code]

cada pessoa pode ter 1 conhecido e cada conhecido pode ter 1 conhecido, se eu quizesse seguir essa linha de pessoas conhecidas e pegar o 10º nivel de conhecido eu faria.

Conhecido nivel10 = pessoa.conhecido.conhecido.conhecido.conhecido.conhecido.conhecido.conhecido.conhecido.conhecido.conhecido;

obs:isso é possivel usando loop, mas nao vem ao caso…

cada conhecido estaria na Arvore de Referências (HEAP) com sua referência, quando você “parar em uma referência” ele te devolve o objeto do Pool de Objetos

sem desenhos é dificil explicar isso…

Isso aqui é só uma definição:

public class Animal{ String nome; int size, age; }

Ou seja, você está explicando para o java que, ao criar um animal, existirão 2 variáveis inteiras de nome size e age, e um objeto do tipo string associados. Porém, a definição não cria nada. Aqui, não existe memória sendo alocada, nem endereços. Existe só uma explicação, um plano, para quando uma instância ocorrer.

E quando essa instância ocorre? No momento do “new”:

Animal meuAnimal = new Animal();

Quando o Java vê isso, o que ele faz?
a) Ele verifica que áreas de memória precisará criar: No caso, a definição da classe animal indica que são 3: dois ints e uma referência.
b) Ele cria as três áreas de memória e as associa aos apelidos meuAnimal.nome, meuAnimal.size e meuAnimal.age;
c) Ele procura na definição por um construtor, para inicializar essas áreas de memória com algum valor. No caso dessa classe que não tem, irá fazer com que o java faça a construção padrão, inicializando size a age com 0, e a referência com null.

Note que não há conflito. Se um novo animal for criado,

Animal outroAnimal = new Animal();

Outras 3 variáveis serão criadas:
outroAnimal.nome outroAnimal.size e outroAnimal.age

Agora, você pode se perguntar. Mas e quando eu uso uma dessas variáveis diretamente dentro de um método de animal?

public void fazAlgo() { System.out.println(nome + " " + age); }

Novamente, você aqui você está só definindo coisas, ou seja, explicando para o Java o que fazer com as variáveis do animal que for chamado.
Porém, quando você faz:

meuAnimal.fazAlgo();

Ou

outroAnimal.fazAlgo();

Você especifica um animal “concreto”, ou seja, agora o java sabe de que animal específico você está falando.
Assim, ele poderá usar as variáveis corretas desse animal dentro do método.

Um exemplo mais abstraído desta explicação do ViniGodoy se encontra no livro Head First: Java, da Kathy Sierra. Eu também demorei a entender como funcionava esse paradigma, até o dia que tive a oportunidade de ler o livro, que por sinal é muito bom!

Te recomendo a leitura!

:wink:

Consegui entender, obrigado! Dei uma lida também sobre alocação dinâmica e deu uma boa clareada, já que quase tudo em Java é objeto.

Pessoal, seria mais ou menos dessa maneira:

public class Cadastro{

    int codigo;
    long tipo;

}

public class Test{

    public static void main (String [] args){
        Cadastro cadastro= new Cadastro();

    }

}

As posições de memória seriam representadas +/- dessa maneira:

Obs: no caso dessa classe o endereço de memória inicia a partir do número 126.

Onde a variável cadastro referencia duas outras variáveis, as variáveis codigo e tipo. E para poder acessar elas seria obrigatório o uso da primeira referencia, no caso a variavel cadastro?