[RESOLVIDO] (Kathy Sierra - SCJP 1.6) Dúvida no exercício do teste

7 respostas
jaumzera

Olá amigos.
No livro de preparação para a certificação SCJP 1.6 da Kathy Sierra encontei o seguinte exercício:

class CardBoard {
    Short story = 5;
    CardBoard go(CardBoard cb) {
        cb = null;
        return cb;
    }
 
    public static void main(String[] args) {
        CardBoard c1 = new CardBoard();
        CardBoard c2 = new CardBoard();
        CardBoard c3 = c1.go(c2);
        c1 = null;
        // do stuff
    }
}

A questão pergunta quantos objetos serão elegíveis à coleta de lixo quando a execução chegar à “// do stuff”.
A resposta dada pelo livro é 2 e a justificativa é a seguinte: “apenas 1 objeto CardBoard (c1) é elegível para coleta, mas ele tem um objeto wrapper Short (o objeto story) que também é elegível”.

Porém, no mesmo capítulo do livro, uma passagem diz que objetos wrappers no escopo de um byte (-128 à 127) referenciam os mesmos objetos, por questões de economia de memória. Cheguei até mesmo a colocar “System.out.println(c1.story == c2.story)” no código acima e ele retorna true, como eu esperava. Portanto, se c1 possui o mesmo objeto story que c2, story não estará elegível à coleta de lixo. Estou certo? Desta forma, a resposta correta seria “somente 1 objeto (c1) está elegível à coleta de lixo”.

Obrigado, amigos.

7 Respostas

moacirjava

Bom, eu também estou estudando para a certificação ha um bom tempo, mas confesso que não estou “afiado” rsrsr. Não resisti ao seu tópico e vou palpitar rsrsr.
No método:

CardBoard go(CardBoard cb) {  
         cb = null;  
         return cb;  
     }

Ele retorna sempre null e nunca cria um objeto wrapped Short. Já nas linhas 9 e 10 é instanciado objetos do tipo CardBoard e consequentemente os objetos de instância da classe ou seja, o objeto Short.
Na linha 11 o objeto c3 recebe o valor null. Na linha 12 o objeto c1 recebe null já se tornando qualificado para o coleta e o objeto Short que ele apontava tem sua referência perdida, daí a resposta do livro dizendo que são dois objetos para serem recolhidos pelo GC.

Dá uma lida no capítulo 3 página 144, subtítulo Anulando uma referência essa referência eu tirei do livro 1.5, mas talvez no livro 1.6 a página seja diferente mas não seu conteúdo.

Espero ter ajudado.

jaumzera

Olá moacirjava! Primeiramente, obrigado por responder.
Então… no código, se você comparar c1.story == c2.story, a resposta é true. Com isso podemos concluir que eles referenciam o mesmo objeto. Pois neste mesmo capítulo existe um tópico dizendo que objetos que encapsulam primitivos no escopo -128 a 127 referenciam os mesmos objetos para economizar memória.
Quando c1 recebe null, fica elegível à coleta de lixo, no entanto, o objeto story que ele referenciava ainda está referenciado por c2.story. Com base nisso, story não seria elegível à coleta de lixo. É essa minha dúvida. Somente c1 é elegível, ou seja, um único objeto, já que c3 nunca foi instanciado e, portanto, não será elegível para coleta.

moacirjava

jaumzera:
Olá moacirjava! Primeiramente, obrigado por responder.
Então… no código, se você comparar c1.story == c2.story, a resposta é true. Com isso podemos concluir que eles referenciam o mesmo objeto. Pois neste mesmo capítulo existe um tópico dizendo que objetos que encapsulam primitivos no escopo -128 a 127 referenciam os mesmos objetos para economizar memória.
Quando c1 recebe null, fica elegível à coleta de lixo, no entanto, o objeto story que ele referenciava ainda está referenciado por c2.story. Com base nisso, story não seria elegível à coleta de lixo. É essa minha dúvida. Somente c1 é elegível, ou seja, um único objeto, já que c3 nunca foi instanciado e, portanto, não será elegível para coleta.

c1.story e c2.story são objetos diferentes apontando para o mesmo local de memória, não?

jaumzera

moacirjava:

c1.story e c2.story são objetos diferentes apontando para o mesmo local de memória, não?

Me corrijam se eu estiver errado, mas eu diria que story de c1 e story de c2 são variáveis de referência diferentes, mas o objeto (no heap) é o mesmo.
Se a comparação c1.story == c2.story retorna true, elas referenciam o mesmo objeto.

moacirjava

jaumzera:
moacirjava:

c1.story e c2.story são objetos diferentes apontando para o mesmo local de memória, não?

Me corrijam se eu estiver errado, mas eu diria que story de c1 e story de c2 são variáveis de referência diferentes, mas o objeto (no heap) é o mesmo.
Se a comparação c1.story == c2.story retorna true, elas referenciam o mesmo objeto.

Mesmo assim volto a dizer, são dois objetos apontando para o mesmo local de memória.

jaumzera

Posso não estar entendendo o que você quer dizer com “objeto”, entretanto, até onde eu sei, story em c1 não é o objeto Short, mas sim uma variável de referência ao objeto Short.
De qualquer forma, mesmo utilizando a sua interpretação, quando é atribuído null à c1, c1 fica disponível para coleta de lixo, mas o objeto referenciado por c1.story não, pois ainda é possível acessá-lo através de c2.story, pois c1.story == c2.story. É aí que páira a minha dúvida.

De qualquer forma, muito obrigado moacirjava.

jaumzera

Olá amigos…
Pra quem possa vir a ter a mesma dúvida que eu, o problema é o seguinte: versão traduzida.
Estive dando uma olhada na versão em inglês hoje e percebi que o valor inicial de “story” é, na verdade, 200 (na versão em português que eu tenho é 5).
Desta forma, 200 não está no escopo das variáveis do pool de constantes e o teste c1.story == c2.story retorna false.
Mandei um e-mail pro pessoal da AltaBooks mas creio que eles vão demorar um pouco pra responder.
De qualquer forma, fica a dica.

Criado 31 de dezembro de 2009
Ultima resposta 31 de dez. de 2009
Respostas 7
Participantes 2