Como fazer Singleton em Java? Tipos de inicialização, comparação e pontos a serem lembrados
Publicados: 2020-10-07Uma classe singleton em Java é definida como aquela classe que possui apenas um objeto, ou seja, apenas uma instância da classe. A restrição da instância a apenas uma por classe ajuda na codificação de programas específicos que requerem apenas uma instância da classe. A única instância de uma classe singleton recebe um ponto de acesso global.
A classe Singleton é um dos padrões de design importantes na programação Java. As classes singleton ajudam a limitar os recursos e a otimizá-los; é muito usado em conexões de banco de dados ou sockets. Existem sintaxes de implementação para classe singleton, e um bom desenvolvedor deve saber sobre isso. Vamos ver a implementação da classe singleton em Java.
Aprenda programas de engenharia de software online das melhores universidades do mundo. Ganhe Programas PG Executivos, Programas de Certificado Avançado ou Programas de Mestrado para acelerar sua carreira.
Leia: Arquitetura e componentes Java explicados
Índice
Inicialização
A inicialização de um singleton em Java é feita através de um construtor privado. Construtores privados ajudam em outras classes não sendo capazes de criar a mesma instância de sua classe singleton. Existem cinco tipos de inicialização da classe singleton em Java, listados abaixo:
1. Inicialização ansiosa
Um método público comumente chamado de getInstance() é criado. Esse método ajudará a fornecer apenas um ponto de entrada para criar uma instância da classe, tornando-a uma classe singleton. A instância da classe em inicialização antecipada é criada no momento do carregamento da classe.

Esse tipo de técnica de inicialização cria a instância da classe automaticamente, mesmo que o usuário não a esteja usando. Isso pode causar problemas de memória e comprimento desnecessário no código. Para combater o problema de vazamento de memória, vejamos outro tipo de técnica de inicialização para uma classe singleton em Java.
2. Inicialização lenta
A instância da classe é inicializada no próprio método getInstance() na inicialização lenta. O método na inicialização lenta irá verificar se a instância da classe foi criada ou não e se não for criada, então apenas cria uma instância, resolvendo assim o problema de vazamento de memória.
O método criado na inicialização lenta é estático e tem um objeto do tipo de retorno. A instância singleton na inicialização lenta não será criada até que o método getInstance() seja chamado pela primeira vez.
3. Inicialização lenta com método de bloqueio duplo
Este método é usado no momento de mais de um thread. Se estivermos usando dois threads no programa, e ambos puderem ser acessados através da instrução 'if' na inicialização quando a instância for nula, isso criará uma situação de conflito e você poderá encontrar erros.
Este problema é resolvido pelo Método Double Lock em que apenas uma thread entra por vez no bloco sincronizado para a inicialização da instância enquanto a outra thread está bloqueada. Quando o primeiro thread sai do bloco sincronizado, apenas o segundo thread entra e cria outra instância. Por padrão, o segundo encadeamento não verifica se a instância é não nula ou não.
4. Método de carregamento lento
A classe interna aninhada é criada neste método e funciona em princípios de JLS (Java Language Specifications). Não haveria membros de dados estáticos na classe; A JVM não criará uma instância da classe. A instância só seria criada sob demanda quando invocamos o método getInstance().
Você não precisa sincronizar o método para inicialização e carregamento, pois esse método ajuda na sincronização automática de todas as invocações de obtenção de Instance().
5. Método Enums
Várias instâncias de uma classe singleton ainda podem ser criadas por serialização e reflexão nos métodos acima. No caso de fazer uma classe singleton estrita, este método pode ser usado. Os campos Enums são usados neste método que é uma constante e é executado apenas em tempo de compilação.

Um Enum é a instância do tipo Enum e será construído somente quando o tipo Enum for invocado/chamado pela primeira vez no código. Esse método restringe a clonagem da instância e cria uma classe singleton perfeita.
Leia também: Os 12 principais programas de padrão em Java que você deve fazer check-out hoje
Serialização e Reflexão
A serialização ajuda no transporte de objetos Java de uma JVM (Java Virtual Machine) para outra. A serialização é um dos métodos usados para criar várias instâncias de uma classe. A serialização converte o objeto em um fluxo de bytes e, em seguida, a transferência é feita.
O fluxo de bytes ajuda a recriar o objeto em alguma outra JVM usando o processo de desserialização. Ele ajuda vários sistemas a se comunicar e compartilhar objetos entre eles. Isso ajuda na sincronização cruzada de JVM, pois os objetos funcionarão em diferentes JVMs.
A reflexão também é um método de clonagem de objetos em Java. Reflection é uma API que nos ajuda a conhecer a classe de qualquer objeto e métodos desconhecidos dessa classe específica que pode ser acessada por meio do objeto. A reflexão é amplamente utilizada por programadores para modificar o comportamento de classes e métodos em tempo de execução.
Os três principais comandos usados na reflexão são getClass() para conhecer a classe à qual o objeto pertence, getConstructors() para obter os construtores públicos da classe do objeto, getMethods() para conhecer os métodos públicos da classe sob observação.
Classe Normal vs Classe Singleton
Uma classe padrão em Java usa construtores para inicializar a si mesma, enquanto usamos o método getInstance() para inicializar uma classe singleton. Também podemos usar o mesmo nome de classe e método. Criamos um objeto primeiro para classes normais e depois usamos seus métodos e propriedades.
Por outro lado, em uma classe singleton, criamos uma instância usando a propriedade estática da classe e, em qualquer ponto do código, essa classe específica retornará apenas uma única instância.
Além de muitas vantagens das classes singleton, existem algumas brechas também, como métodos de teste de unidade de adulteração de classes singleton, se os objetos e métodos estiverem fortemente acoplados. Você terá que dedicar uma classe totalmente funcional a um singleton nesse caso.
Dependências ocultas também são criadas pela classe singleton às vezes, pois a referência da classe singleton é passada para outros métodos e não é totalmente transparente, tornando difícil para os codificadores/desenvolvedores acompanhar os métodos e classes. Deve-se manter essas deficiências em mente antes de criar um padrão singleton e deve-se tentar minimizá-lo.
Pontos para fazer uma classe Singleton perfeita
1. Os pontos que devem ser focados para fazer uma classe singleton perfeita são os seguintes:
2. Se você estiver criando vários threads em uma classe singleton, certifique-se de que todos os threads não inicializem a classe singleton ao mesmo tempo. Deve-se tentar fazer classes singleton thread-safe.

3. Faça a prova de reflexão de sua classe singleton, alterando a visibilidade do construtor para o público em tempo de execução e certificando-se de que haja apenas uma instância de qualquer classe singleton específica.
4. Se houver vários encadeamentos, você pode usar um modificador volátil que impede que um encadeamento veja o estado inicializado de outros encadeamentos. Um modificador volátil funciona no relacionamento acontece antes em que a gravação acontece em um encadeamento antes que qualquer outro encadeamento possa lê-lo.
Deve ler: Idéias interessantes de projetos Java para iniciantes
Conclusão
As classes singleton são usadas para fazer conexões personalizadas com o banco de dados ou qualquer programa no qual você deseja controlar os métodos e instâncias da classe.
Se você deseja melhorar suas habilidades em Java, você precisa colocar as mãos nesses projetos Java. Se você estiver interessado em aprender mais sobre Java, desenvolvimento de pilha completa, confira o Programa PG Executivo do upGrad & IIIT-B em Desenvolvimento de Software - Especialização em Desenvolvimento de pilha completa, projetado para profissionais que trabalham e oferece mais de 500 horas de treinamento rigoroso, 9 + projetos e atribuições, status de ex-alunos do IIIT-B, projetos práticos práticos e assistência de trabalho com as principais empresas.