Método construtor em Java, Vilão? Mocinho? Vamos entender!

gabrielsantosba

Gabriel Bahia.

Posted on August 4, 2022

Método construtor em Java, Vilão? Mocinho? Vamos entender!

Quem são os construtores de classe em Java?

Construtores de classe no Java existem de forma implícita, ou seja, naturalmente eles são gerados, mesmo que não haja declaração por parte de nós “devs”, a mãezona JVM trata de criar eles, isso por que precisa ser alocado um espaço na memória para esse novo objeto que você acabou de dar um new, podemos entender assim, o construtor executa operações necessárias para inicializar a classe antes que os métodos sejam invocados ou os campos sejam acessados,( penso até que poderíamos pensar em um construtor como um inicializador ***), os atributos ganham valores padrões, **ex: atributos do tipo String ganham valor null, primitivos do tipo número ganham valor 0.0, os construtores(constructors) são usados para gerar atomicidade, ou seja, ou cria o objeto em um estado válido, ou não cria, dessa forma garante-se que para aquele objeto tenha sempre um padrão “criacional”( nem sei se essa palavra existe rsrs), mas você entendeu certo?

Além do mais, em alguns casos o código fica mais (“ninitinho”) elegante(clean), outra coisa o construtor de uma classe é um método(método construtor, método especial), você sacou certo? Resumindo é um método cuja finalidade é construir… Obvio rsrsr!

Agora guarda essa dúvida aí, tem como destruir um objeto em Java? Se não sabe, vem comigo que vou te responder.

Como usar métodos construtores de classe em Java?

Primeiro você precisa saber que não vou aqui fazer tutorial de como criar um construtor de uma classe, isso é muito básico(até a própria IDE faz), o que vou fazer aqui é te trazer dicas básicas de onde é como usar, também algumas sacadas de cuidados na criação de um construtor de classe em Java.

Estamos acertados?

Como você fechou negócio comigo, vamos começar pelas boas práticas.

Boas práticas na criação de Construtores(Constructors) de classe em Java.

Validação de objetos.

Vamos lá, mentaliza aí uma classe Aluno, agora pensa um cenário onde você precisa validar os dados da criação de um objeto dessa classe na sua criação, é caso a validação de algum desses dados falhar(sei lá, o atributo nome não está passado na criação), então esse objeto não **deve ser criado, nesse caso um construtor ajuda bastante, pois logo na criação do objeto caso não atenda a definição de atributos determinada no método construtor vai ocorrer erro, (aposto que você pensou, aaa eu poderia validar com **if else, verdade, mas, sejamos elegantes sempre que possível rsrsr, agora vamos pensar em outro cenário, se você tivesse que validar também o objeto (MensalidadeAluno) somente se o objeto Aluno **tiver sido criado em um estado válido, **lembrando que esses objetos podem ser criados de forma independente, nesse caso também usando o construtor da classe podemos controlar isso. Por que, a validação do objeto Aluno irá acontecer sempre que um new Aluno for chamado em qualquer parte do código.

No processamento de um objeto.

Novamente mentaliza ai(mentalizou?) em quê? rsrsr, agora é sério, pensa aí em algum processamento de um objeto, pegando o ex: acima: Aluno, esse objeto para ser salvo na base de dados precisa estar pelo menos com sei lá três atributos inicializados, vamos pensar em (nome, telefone, tipo), usando construtores também poderíamos de forma legal validar isso para garantir que um novo objeto(Aluno) criado já esteja em um estado válido, conforme definido no método construtor, claro.

Mais uma… Ordem de execução.

Não sei se você conhece o pattern “Chain of Responsability”(Cadeia de responsabilidade), basicamente nesse pattern temos uma cadeia de objetos onde cada objeto fica responsável por validar uma regra de negócio. Fato é que em um exemplo de uso com 3 regras diferentes, então teríamos possivelmente 3 objetos para implementar esse pattern, eles devem ser chamados de forma encadeada, ou seja, primeiro chama o objeto 1 depois o segundo e assim por diante, até a regra ser validada. Agora imagina, nesse caso precisaremos que não haja falhas na ordem de execução, queremos que a ordem seja seguida certinha, 1..2..3.

Nesse cenário o uso de método construtor é muito útil, pois permite determinar a ordem que cada membro que compõe esse encadeamento seja inicializado, de forma automática ou manual.

Tá Gabriel entendi, mas… sem o uso de método construtor como ficaria?

Bom, sem nosso amigo construtor a JVM em tempo de execução(runtime) é quem vai determinar a ordem de inicialização de cada objeto, isso poderá seguir a ordem determinada ou não, isso mesmo, não necessariamente vai seguir o fluxo que você gostaria que os objetos fossem instanciados, enfim, não fica no controle do Dev sem uso de um construtor neste caso. Cá pra nós, lidar com situações que precisam de uma sequência e delegar isso para ser feito de forma automática… rummm é meio tenso rsrsr. Agora pegando esse entendimento poderíamos também validar corretamente o fluxo de um encadeamento ou algo assim, tipo usar uma validação para se certificar que objeto 2 foi chamado após objeto 1 é assim por diante.

O que não é legal fazer na criação de construtores de classe?

Muitos Construtores.

Esse artigo inclusive nasceu a partir do momento em que eu vi em um projeto qual eu estava atuando, algumas classes tinham construtores excessivos(na minha opinião) eram classes do tipo *DTO, tinham até 4 construtores diferentes, fui implementar um desses construtores e fiquei perdido, não sabia qual construtor usar, parei naquele momento reflexivo como melhorar isso? Foi aí que parei para pensar, isso é uma boa prática? Sim, me fiz essa pergunta porque um dos recursos da programação O.O é justamente a sobrecarga de método(override method), fiz algumas pesquisas, vi até um post no *GUJ com vários comentários sobre o assunto(tinha até comentários do Paulo Silveira(com foto de adolescente rsrs), CEO da Alura.

Achei interessante a discussão, o que pude abstrair foi que todos concordavam que não fica legal vários métodos construtores de formas diferentes, li até que algumas empresas definem que deve haver apenas 2 métodos construtores, 1 vazio, é 1 com as devidos atributos, justamente para não virar bagunça, então fica a dica, nada de chuva de construtores rsrsr.

Muitos parâmetros estão sendo passados no construtor.

Outra coisa importante, com base no nosso entendimento acima, podemos entender que não faz muito sentido ter um construtor se nenhum dos parâmetros vai receber dados obrigatórios para ter um estado válido, ou então se for possível que esses valores possam ser inicializados de forma padrão, pensa comigo, imagina uma quantidade monstra de parâmetros num construtor, a manutenção de um código com várias implementações assim, fica no mínimo triste, dá canseira só de olhar.

Afinal, devo ou não devo usar métodos construtores em Java?

Vamos alinhar um fato, construtores não são obrigatórios, toda classe precisa ter um construtor definido? A resposta é não, lembrando que estamos falando da linguagem Java, em outras linguagens não sei bem ainda como funciona, pode até haver alguma que obrigue a criação, mas em Java não.

Outra coisa, outro motivo que me levou a construir esse artigo é, percebi ser importante saber o porquê de criar um construtor é o por que não, em meus estudos vi uma declaração que dizia assim “Se você não sabe porque está criando um construtor provavelmente está criando-o desnecessariamente” por isso é importante entender como funciona o uso de construtor na criação de um objeto, sem esse entendimento não é possível entender quando o construtor é necessário. Agora olhando por outro ângulo, se nem mesmo passou por nossa mente que determinado objeto precisa da implementação de um construtor, que talvez seria melhor com o uso dele, bom nesse caso precisamos estudar mais, mas calma, por isso estamos aqui é por isso escrevi esse artigo, então tá tudo certo.

Matando a cobra e mostrando o pau.

(eu sempre quis escrever isso** rsrsr)**

No geral a preferência, sempre que possível, é que os membros sejam ou inicializados por padrão, ou individualmente no código que vai consumi-lo.

tá, como seria essa inicialização padrão?

variavel = valor

ou

Aquele velho é bom…

CLASSE classe = new CLASSE();

classe.setNome();

isso é tão familiarrsrsr

Um construtor com dados definidos deve existir se realmente ele for necessário e só deve receber os parâmetros mínimos para gerar um estado válido manipulando a menor quantidade possível de membros.

Finalizando nosso papo, não fique sem criar um construtor quando ele vai trazer ao código legibilidade ou mesmo vantagem, seja para manutenção futura para facilitar testes, etc.

Tenha em mente…

  • Construtores nunca devem trazer efeitos colaterais

  • Pensando em **SOLID**, um dos princípios é justamente a questão da responsabilidade única, então um construtor só deve construir objetos válidos.

Assim…. respondendo a pergunta que fiz acima.

Não tem como destruir um objeto em Java.

até a versão 11 que foi até onde tenho estudado, o **Garbage Collector** o cara que poderíamos invocar via código para fazer isso, não tem como chamarmos ele via código Java, por que esse bonitinho é executado quando a JVM quer, da forma que ela quer é pronto, quem manda é ela rsrsr, o que podemos fazer é ela, atribuir null para uma para o objeto em questão, e retirar todas as referências que tenha para ele, dessa forma ele será elegível para a coleta, mas…. não há como saber quando ele realmente será coletado…

Tem muito mais para se aprender sobre método construtor em java: sugiro uma lida na documentação -> https://docs.oracle.com/javase/tutorial/reflect/member/ctor.html

Fechou? Papo meio denso mas te espero na próxima.

💖 💪 🙅 🚩
gabrielsantosba
Gabriel Bahia.

Posted on August 4, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related