Vídeos novos: segunda, quarta e sexta · 8h

Construtores em Java: o erro que todo iniciante comete

Construtor padrão, sobrecarga, this(...) e o motivo de o seu código parar de compilar.

O construtor é o bloco de código executado quando você cria um objeto com new. A função dele é deixar o objeto num estado válido desde o primeiro instante.

public class Produto { private String nome; private double preco; public Produto(String nome, double preco) { this.nome = nome; this.preco = preco; } } Produto p = new Produto("Teclado", 199.90);

Repare: o construtor tem o mesmo nome da classe e não tem tipo de retorno — nem void.

O erro clássico

Se a sua classe não declara nenhum construtor, o compilador cria um construtor padrão, sem parâmetros. Mas, no momento em que você escreve qualquer construtor, esse padrão deixa de existir:

Produto vazio = new Produto(); // erro: constructor Produto in class Produto cannot be applied to given types

É por isso que, de repente, frameworks como o JPA começam a reclamar: eles precisam de um construtor sem argumentos. A solução é declará-lo explicitamente:

protected Produto() { } // exigido pelo JPA

O outro erro: colocar void

public void Produto(String nome) { ... } // ⚠ isto é um MÉTODO, não um construtor!

Compila sem erro, mas nunca é chamado pelo new. Os atributos ficam nulos e você passa horas sem entender por quê.

Sobrecarga e this(...)

Uma classe pode ter vários construtores, com parâmetros diferentes. Para não repetir código, um chama o outro com this(...):

public Produto(String nome) { this(nome, 0.0); // reaproveita o construtor completo } public Produto(String nome, double preco) { if (preco < 0) throw new IllegalArgumentException("Preço inválido"); this.nome = nome; this.preco = preco; }

Construtores e herança

Na herança, o construtor da classe filha sempre chama o da classe mãe com super(...). Se você não escrever, o Java tenta chamar super() sem argumentos — e, se a mãe não tiver esse construtor, o erro volta a aparecer.

public class ProdutoDigital extends Produto { private String urlDownload; public ProdutoDigital(String nome, double preco, String url) { super(nome, preco); this.urlDownload = url; } }

E os records?

Para classes que só carregam dados, um record gera o construtor, os getters, o equals e o toString por você — e ainda permite validar no construtor compacto:

public record Preco(double valor) { public Preco { if (valor < 0) throw new IllegalArgumentException("Preço inválido"); } }
Lembre-se: escreveu um construtor com parâmetros? O construtor vazio sumiu. Se precisar dele, declare-o.