![translation](https://cdn.durumis.com/common/trans.png)
Esta é uma postagem traduzida por IA.
Selecionar idioma
Texto resumido pela IA durumis
- Um Singleton é uma classe que permite a criação de apenas uma instância, sendo utilizada para criar objetos sem estado ou componentes de sistema exclusivos.
- Existem três métodos para criar um Singleton: usar um membro estático público como um campo final, fornecer um método de fábrica estático ou usar um tipo de enumeração, sendo este último o mais desejável.
- Ao serializar uma classe Singleton, é necessário implementar Serializable, declarar todos os campos de instância como transient e sobrescrever o método readResolve().
Singleton
O conceito de Singleton
Singleton é uma classe que permite a criação de apenas uma instância. Um exemplo típico de Singleton é um objeto sem estado ou um componente do sistema único. No entanto, as classes Singleton são difíceis de testar, a menos que o tipo seja definido como uma interface e sua implementação seja definida separadamente.
Como criar um Singleton
Método de usar um membro estático público como um campo final
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {
}
public void speak() {
System.out.println("elvis");
}
O construtor privado é chamado apenas uma vez ao inicializar a instância Elvis, garantindo que ela seja a única em todo o sistema. No entanto, o construtor privado pode ser chamado usando AccessibleObject.setAccessible(), mas esse método de modificação por reflexão pode ser bloqueado lançando uma exceção ao criar o segundo objeto.
- Vantagens
- É evidente na API que a classe é um Singleton.
- Conciso.
Método de fornecer um método de fábrica estático público
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() {
}
public static Elvis getInstance() {
return INSTANCE;
}
public void speak() {
System.out.println("elvis");
}
Este método também garante que seja a única instância em todo o sistema, exceto para modificações por reflexão. Apenas o campo foi alterado para privado e o retorno do objeto está sendo realizado usando um método de fábrica estático.
- Vantagens
- É possível mudar para algo que não seja um Singleton sem alterar a API.
- Por exemplo, o método de fábrica estático pode ser usado para retornar uma instância diferente para cada thread.
- Se você quiser, pode mudar para um método de fábrica de Singleton genérico.
- A referência de método do método de fábrica estático pode ser usada como um
fornecedor.
- Por exemplo, em vez de Elvis::getInstance, você pode usar Supplier<Elvis>.
- É possível mudar para algo que não seja um Singleton sem alterar a API.
Se você não precisar usar as vantagens acima, é melhor usar o primeiro método.
Método de usar um tipo de enumeração
public enum Elvis {
INSTANCE;
public void speak() {
System.out.println("elvis");
}
O método mais desejável é usar um tipo de enumeração. Em comparação com os dois métodos acima, ele é mais seguro contra ataques por reflexão e o código é mais limpo. Além disso, como discutiremos abaixo, os dois métodos acima têm a desvantagem de requerirem código adicional ao serializar.
No entanto, você deve ter cuidado porque, embora o Singleton que deseja criar possa herdar uma interface, ele não pode herdar uma classe.
Pontos a serem observados ao serializar uma classe Singleton
Se você quiser serializar uma classe Singleton criada usando o primeiro ou o segundo método acima, além de simplesmente implementar Serializable, você deve declarar todos os campos de instância como transient e sobrescrever o método readResolve().
private Object readResolve throws ObjectStreamException {
return INSTANCE;