Instanciação de objetos (no corpo da classe vs. no método construtor)

5 respostas
pedroabs

Qual a diferença em instanciar um objeto assim:

public class Pessoa {
    private Telefone tel = new Telefone();
}

ou assim:

public class Pessoa {
    private Telefone tel;

    public Pessoa(){
        tel = new Telefone()
    }

}

repare que no primeiro código eu declaro e instancio a variável diretamente na classe.

no segundo código, eu declaro a variável como privada e a instancio no método construtor.

Gostaria de saber:
1) Qual a diferença entre essas duas abordagens?
2) Em que momento esses objetos são criados?

5 Respostas

E
public class Pessoa {  
     private Telefone tel = new Telefone();  
 }

é uma abreviação para:

public class Pessoa {  
     private Telefone tel;
     {
        tel  = new Telefone();  
     }
 }

E esse “bloco anônimo” é algo que é executado por todos os construtores, imediatamente depois da chave. Por exemplo, se a classe Pessoa fosse assim:

public class Pessoa {  
     private Telefone tel;
     {
        tel  = new Telefone();  
     }
     public Pessoa (String nome) { 
         this.nome = nome;
     }
 }

ela seria equivalente a (em termos de execução):

public class Pessoa {  
     private Telefone tel;
     public Pessoa (String nome) { 
         tel  = new Telefone();  
         this.nome = nome;
     }
 }

Dica: é mais fácil entender a atribuição direta aos membros que o “bloco anônimo”. De qualquer maneira, você sempre deve SABER o que está fazendo.

Marky.Vasconcelos

As vezes para inicializar os atributos voce precisa de algum argumento que veio de outro lugar, e provavelmente voce tera acesso a isso no construtor como resultado de algum método.

gomesrod

Essa foi uma boa explicação, mas só para completar acho interessante colocar a principal vantagem de cada um deles na prática:

-> No primeiro jeito, o código fica mais simples e “compacto”.
-> Já o segundo permite que você execute alguma lógica para obter o valor e daí atribuir para a variável.

E

De fato, o bloco anônimo é interessante porque muitas vezes tentar instanciar algo lança uma exceção que tem de ser tratada ou ignorada. Por exemplo:

MessageDigest digest;
    {
        // Você sabe que essa exceção nunca será lançada, mas como é uma "checked exception" você
        // é obrigado a tratá-la. Portanto você é obrigado a usar um bloco anônimo, ou copiar este
        // código para cada construtor. 
        try { digest = MessageDigest.getInstance ("MD5"); } catch (UnknownAlgorithmException ex) {}
    }
marcosvidolin

Olá
A meu ver a diferença esta no momento em que o objeto é “instanciado”.

Neste caso, sua classe sempre terá um objeto instanciado da classe Telefone usando o construtor padrão, ou seja, imagine a seguinte situação: Você obriga que todo telefone tenha um DDD. Então sobrescreveria o construtor da classe Telefone por este:

Telefone(int ddd){
   this.ddd = ddd;
}

Sendo assim você não tem mais o construtor padrão Telefone(){}. Ao instanciar a sua classe Pessoa, certamente vai dar pau de compilação, pois como passar o ddd do Telefone?

Isso seria resolvido com a instanciação do objeto Telefone no construtor da classe Pessoa:

Telefone tel;
Pessoa(int ddd) {
   tel = new Telefone(ddd);
}

Espero que o exemplo tenha ajudado!

Galera me corrija, por favor!
[]'s

Criado 30 de setembro de 2009
Ultima resposta 30 de set. de 2009
Respostas 5
Participantes 5