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 JPAO 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");
}
}