Criação e remoção de objetos


Nas aulas anteriores foram apresentados recursos linguísticos para definir classes de objetos, com métodos, atributos, etc. Agora apresentamos recursos linguísticos para especificar a criação, em tempo de execução, de objetos específicos. Assim faz-se a ligação entre o mundo linguístico e o mundo computacional, dando `vida' aos objetos de uma classe.

Criação de Objetos

Para uma classe Classe, cria-se um objeto da mesma executando-se um comando da seguinte forma:
    new Classe(argumentos)
onde argumentos é uma lista, possivelmente vazia, contendo os argumentos a serem passados a um dos inicializadores da classe. Por exemplo, executando os comandos a seguir
    new Conta(12345, 100.0)
    new Conta(1287)
cria-se e inicializa-se duas contas, de acordo com os argumentos especificados e os dois inicializadores de Conta: o inicializador usado no primeiro comando inicializa o número e o saldo da conta, enquanto o inicializador usado no segundo comando só inicializa o saldo da conta.

De fato, os comandos acima, como todo comando de criação, além de criar e inicializar um objeto retorna como resultado o nome (identificador) deste objeto (não o objeto propriamente dito); isto é, uma referência (ponteiro) para este objeto. Esta referência é interna ao sistema Java, não sendo diretamente visível ao programador. No entanto, a referência pode ser armazenada em um atributo ou em uma variável local a um método, de forma que o objeto possa ser futuramente acessado:

    Conta c1, c2, c3;

    c1 = new Conta(12345, 100.0);
    c3 = new Conta(1287);
Como a variável (ou o atributo) armazena o nome de um objeto, podemos mandar uma mensagem para este objeto simplesmente referenciando a variável. Por exemplo, o seguinte código
    var.mensagem()
é responsável por enviar a mensagem mensagem() ao objeto cujo nome esteja armazenado na variável var no momento da execução. No caso acima, a execução de
  c1.printSaldo()
imprimiria o valor 100.00, o saldo da conta cuja referência está armazenada em c1.

Note o contraste entre os atributos e variáveis locais de tipo primitivo (int, boolean, double, etc.) e os atributos e variáveis de tipo classe (Conta, Livro, etc.). Enquanto os primeiros estão associados (armazenam) valores, os outros estão associados a referências (nomes, identificadores) para objetos, ao invés de objetos propriamente.

Como a variável c1 armazena simplesmente o nome de um objeto, executando-se a atribuição

    c2 = c1;
apenas armazena-se em c2 o mesmo nome de objeto armazenado em c1; atribuição não leva a criação de um novo objeto! Assim, atributos diferentes podem referenciar o mesmo objeto; neste caso, dizemos que o objeto é compartilhado. De fato, executando-se
    c2.printSaldo();
    c1.printSaldo();
pode-se verificar que o saldo da mesma conta será impresso duas vezes.

Remoção de Objetos

Como vimos acima, objetos podem ser criados dinamicamente mediante o uso do comando new. Também sabemos que os nomes (referências) dos objetos são armazenados em variáveis ou associadas a atributos. Quando o nome de um objeto deixa de estar armazenado em uma variável ou associado a algum atributo, o sistema de garbage collection de Java automaticamente destrói (remove da memória do computador) o objeto. Em Java, não é necessário, nem possível, remover explicitamente um objeto.

No entanto, podemos especificar que determinadas operações devem ser executadas antes da destruição de qualquer objeto de uma classe específica. Para isso, basta definir o método finalize na respectiva classe:

    void finalize() {
        ...
    }
Este método não tem parâmetros nem devolve resultados, e é automaticamente invocado pelo sistema Java antes da destruição de um objeto da classe correspondente. Em particular, o método finalize é útil quando o objeto a ser destruído mantém alguns recursos que não podem ser liberados pelo garbage collector de Java. Por exemplo, a remoção de um objeto que estava usando recursos do sistema operacional implica no bloqueio desses recursos até que o programa deixe de funcionar.


Paulo Borba (phmb@cin.ufpe.br)