Quando eu tenho uma hierarquia de classes e instancio um objeto da subclasse (Subclasse obj = new Subclasse()), eu acabou criando objetos das superclasses também, não é?
Assim, quando o garbage collector rodar, ele irá limpar não apenas o objeto da subclasse, mas também os objetos que serviram como base para ela (as n superclasses), incluindo Object.
até onde sei é criado apenas um objeto do tipo da subclasse.
ECO2004
[email removido:
]ECO2004,
até onde sei é criado apenas um objeto do tipo da subclasse.
A instanciação de um objeto da subclasse faz com que seja:
1-alocada memória para esse objeto da subclasse;
2-o seu construtor é chamado [para inicializar as variáveis de instância]
Contudo, a primeira coisa que um construtor de subclasse faz é chamar o construtor da superclasse.
Por isso pergunto se são criados objetos das superclasses. Não li em nenhum lugar, mas logicamente a superclasse seria instanciada implicitamente, as suas variáveis inicializadas e, depois, o controle voltaria para o construtor da subclasse, que inicializaria as suas variáveis de instância.
Correto?
thiago_pco
As classes funcionam como “estruturas” para a criação de um objeto.
A questão da herança é pelo fato da reutilização do código.
Já pensou numa classe que tenha 3 níveis de herança, e ao rodar uma criteria(consulta) no BD a mesma retornasse 1.000 registros.
Neste modo teríamos 3.000 objetos na memória em apenas uma simples consulta.
O construtor da superclasse é chamado sim, pois mesmo com a herança os comportamentos de inicialização estão em classes diferentes.
davidbuzatto
O objeto criado é apenas o da subclasse.
Para ter certeza, use um profiler.
O do NetBeans é muito bom.
Se “chamar o construtor” fosse sinônimo de instanciar, um construtor que chama um outro construtor na mesma classe geraria dois objetos, o que não é verdade.
A chamada do construtor da superclasse (até chegar em Object) é feita para garantir que os campos das classes ancestrais sejam inicializados em um estado válido.
[]'s
ECO2004
davidbuzatto:
O objeto criado é apenas o da subclasse.
Para ter certeza, use um profiler.
O do NetBeans é muito bom.
Se “chamar o construtor” fosse sinônimo de instanciar, um construtor que chama um outro construtor na mesma classe geraria dois objetos, o que não é verdade.
A chamada do construtor da superclasse (até chegar em Object) é feita para garantir que os campos das classes ancestrais sejam inicializados em um estado válido.
[]'s
Quando chamo o método Finalize(), isso pode ser em Java, Visual Basic…, posso invocar o da superclasse a partir da subclasse. Isso gera uma chamada de Finalize() em cascata. Bem, quando o Garbage Collector executar, ocorrerá a execução do método Finalize da subclasse primeiro, depois, a chamada do método Finalize da superclasse, e assim por diante. Quando o último método terminar de executar [o da superclasse], esse objeto pode ser reclamado e seu espaço liberado. Depois, o controle volta para a subclasse, onde o seu método Finalize termina e o seu espaço de memória reclamado.
Bem, como é que posso chamar um destrutor de superclasse se não existe um objeto da superclasse em memória?
Isso que não entendo!
davidbuzatto
Destrutor??? Em Java???
Da mesma forma que o construtor foi chamado em cascata para deixar todos os campos em um estado válido, o finalize() é chamado também para fazer o processo inverso. É como se o objeto atual tivese uma cópia de cada método acima da hierarquia, mas isso deve ser (deve, não tenho certeza) controlado pela JVM. Se existisse mesmo um objeto para cada nível da hierarquia, você poderia talvez fazer super.super.super.super.algumMétodo(), o que não é possível. Para ter certeza de tudo isso, vc precisa ler a especificação da JVM.
[]'s
gomesrod
davidbuzatto:
O objeto criado é apenas o da subclasse.
Para ter certeza, use um profiler.
Só de curiosidade, acabei de fazer essa experiência aqui e acontece exatamente isso.
No heap ficam apenas objeto da classe filha, e dentro dela estão todos os atributos da mãe, inclusive os privados (que não são acessíveis para o objeto da classe filha, mas estão lá dentro!).
Pense na classe como uma definição para criar objetos. Uma instância da classe filha é um único objeto que utiliza as definições da classe mãe além das suas próprias, mas o objeto criado é um só.
A chamada ao construtor super() não tem o significado de “crie uma instância da minha classe mãe”. O que essa chamada quer dizer é “execute as rotinas de inicialização da classe mãe primeiro, e depois executarei as minhas próprias”. A mesma idéia com os métodos finalize.
davidbuzatto
gomesrod:
Só de curiosidade, acabei de fazer essa experiência aqui e acontece exatamente isso.
No heap ficam apenas objeto da classe filha, e dentro dela estão todos os atributos da mãe, inclusive os privados (que não são acessíveis para o objeto da classe filha, mas estão lá dentro!).
Na verdade da para acessar usando um pouco de reflection :D No exemplo abaixo eu mudo o valor do atributo "campo" da classe Foo através de um objeto da classe Bar (que herda de Foo e consequentemente herda o campo privado).
O objeto criado é apenas o da subclasse.
Para ter certeza, use um profiler.
Só de curiosidade, acabei de fazer essa experiência aqui e acontece exatamente isso.
No heap ficam apenas objeto da classe filha, e dentro dela estão todos os atributos da mãe, inclusive os privados (que não são acessíveis para o objeto da classe filha, mas estão lá dentro!).
Pense na classe como uma definição para criar objetos. Uma instância da classe filha é um único objeto que utiliza as definições da classe mãe além das suas próprias, mas o objeto criado é um só.
A chamada ao construtor super() não tem o significado de “crie uma instância da minha classe mãe”. O que essa chamada quer dizer é “execute as rotinas de inicialização da classe mãe primeiro, e depois executarei as minhas próprias”. A mesma idéia com os métodos finalize.
Obrigado, gomesrod!
Rodrigo_Sasaki
davidbuzatto:
Destrutor??? Em Java???
Da mesma forma que o construtor foi chamado em cascata para deixar todos os campos em um estado válido, o finalize() é chamado também para fazer o processo inverso…
Só pra constar.
O método finalize não é um “destrutor”, ele é como se fosse um método de callback que a JVM invoca quando ela decide que não existem mais maneiras de acessar o objeto por alguma thread ativa.
A implementação do método na classe Object não faz nada.
A ideia do método era finalizar quaisquer dependências que o objeto pudesse deixar, fechar algum stream por exemplo.