Menu

Construtores em Java: inicializando objetos com new

Como os construtores em Java funcionam: o construtor padrão, construtores parametrizados, this, sobrecarga de construtores e encadeamento com this() e super().

Esta página tem editores executáveis - edite, execute e veja a saída na hora.

Por que os construtores existem

Na página anterior, você criou classes e objetos com new. Um construtor é o código que de fato é executado durante essa chamada a new. Seu único objetivo é devolver um objeto pronto para uso: com todos os campos obrigatórios definidos e sem nenhum estado pela metade.

Um construtor se parece com um método, mas com duas diferenças: ele tem o mesmo nome da classe e não tem tipo de retorno, nem mesmo void.

new Point(3, 4) aloca o objeto e depois executa o corpo do construtor com x = 3 e y = 4. Quando new retorna, p já está totalmente inicializado.

A palavra-chave this

Dentro do construtor acima, os parâmetros se chamam x e y, os mesmos nomes dos campos. this.x significa "o campo x que pertence a este objeto", enquanto x puro se refere ao parâmetro. Sem this, x = x apenas atribuiria o parâmetro a si mesmo e deixaria o campo intocado.

Você só precisa de this quando um parâmetro oculta um campo, mas muita gente o usa em todo lugar por clareza. O erro comum é esquecê-lo quando os nomes coincidem: o código compila, executa e silenciosamente deixa seus campos com os valores padrão (null, 0, false).

O construtor padrão

Se você nunca escrever um construtor, o Java fornece discretamente um construtor padrão: um construtor público, sem argumentos, que não faz nada a mais. Por isso new funcionava em classes que não tinham construtor algum.

A pegadinha: assim que você escreve qualquer construtor, o gratuito some.

class Box {
    int size;

    Box(int size) {       // agora NÃO há construtor sem argumentos
        this.size = size;
    }
}

new Box();   // erro de compilação: o construtor Box() não existe

Se você ainda quiser que new Box() funcione, declare você mesmo o construtor sem argumentos:

Sobrecarga de construtores

Uma classe pode ter vários construtores desde que suas listas de parâmetros sejam diferentes: isso é apenas a sobrecarga de métodos aplicada aos construtores. Cada um oferece uma maneira diferente de construir o objeto.

O Java escolhe o construtor correspondente pelo número e pelos tipos dos argumentos que você passa para new.

Encadeamento com this()

Repare na duplicação acima: cada construtor atribui os campos por conta própria. Você pode evitar isso fazendo um construtor chamar outro com this(...). A chamada deve ser a primeira instrução do construtor.

Agora a inicialização de fato fica em um só lugar. Os construtores menores apenas preenchem os valores padrão e repassam o trabalho. Se você algum dia tentar colocar uma instrução antes de this(...), o compilador a rejeita.

Construtores e super()

Todo construtor chama implicitamente o construtor da superclasse primeiro. Se você não escrever nada, o Java insere um super() oculto (o construtor sem argumentos da superclasse) no topo do corpo. Você trabalhará com isso diretamente assim que começar a criar subclasses, que é o próximo tópico.

class Animal {
    String name;
    Animal(String name) { this.name = name; }
}

class Dog extends Animal {
    Dog(String name) {
        super(name);   // aqui é preciso chamar o construtor do pai explicitamente
    }
}

Como Animal não tem construtor sem argumentos, Dog precisa chamar super(name) explicitamente: não há um super() gratuito para recorrer. Assim como this(), uma chamada a super(...) tem que ser a primeira instrução do construtor.

Próximo: Herança

Os construtores inicializam um único objeto, mas super() já deu uma pista de algo maior: as classes podem se basear em outras classes, reutilizando seus campos, métodos e construtores. Essa relação, uma classe estendendo outra, é a herança, e é a próxima página.

Perguntas frequentes

O que é um construtor em Java?

Um construtor é um método especial que é executado quando você cria um objeto com new. Ele tem o mesmo nome da classe e nenhum tipo de retorno (nem mesmo void). Sua função é colocar o novo objeto em um estado inicial válido, normalmente atribuindo os argumentos do construtor aos campos do objeto.

Qual é a diferença entre um construtor e um método em Java?

Um construtor tem exatamente o mesmo nome da classe e não declara nenhum tipo de retorno, e só pode ser invocado com new quando um objeto é criado. Um método comum tem seu próprio nome, declara um tipo de retorno (ou void) e é chamado em um objeto já existente. Construtores inicializam; métodos realizam o trabalho depois.

O que acontece se eu não escrever um construtor em Java?

O compilador fornece de graça um construtor padrão sem argumentos que não recebe parâmetros e não faz nada além da chamada implícita a super(). Mas no momento em que você escreve qualquer construtor por conta própria, esse construtor gratuito desaparece. Portanto, se você adicionar um construtor parametrizado e ainda quiser que new Thing() funcione, deve declarar o construtor sem argumentos explicitamente.

Coddy programming languages illustration

Aprenda a programar com o Coddy

COMEÇAR