DEV Community

Java Efetivo (livro)
Java Efetivo (livro)

Posted on

Item 83: Utilize a inicialização preguiçosa com parcimônia

O que é inicialização preguiçosa?

  • Definição: Adiar a inicialização de um campo até que ele seja acessado pela primeira vez.
  • Benefícios: Evita inicializações desnecessárias se o campo nunca for usado.
  • Aplicações: Usada para campos estáticos e de instância.

Práticas Recomendadas e Exemplos

  1. Inicialização Normal (Preferível) Simples e eficaz.

Exemplo:

private final FieldType field = computeFieldValue();

Enter fullscreen mode Exit fullscreen mode

Use inicialização normal para a maioria dos campos, salvo necessidade especial.

  1. Inicialização Preguiçosa com Getter Sincronizado Quando usar: Para resolver circularidades de inicialização.

Exemplo:

private FieldType field;

synchronized FieldType getField() {
    if (field == null) {
        field = computeFieldValue();
    }
    return field;
}

Enter fullscreen mode Exit fullscreen mode

3. Prática da Classe Portadora (Para Campos Estáticos)

  • Quando usar: Inicialização preguiçosa eficiente para campos estáticos.

Exemplo:

private static class FieldHolder {
    static final FieldType field = computeFieldValue();
}

static FieldType getField() {
    return FieldHolder.field;
}

Enter fullscreen mode Exit fullscreen mode

Vantagem: Inicializa a classe apenas quando o campo é acessado, com custo mínimo após a inicialização.

4. Prática de Verificação Dupla (Para Campos de Instância)

  • Quando usar: Para desempenho em inicialização preguiçosa em campos de instância.

Exemplo:

private volatile FieldType field;

FieldType getField() {
    FieldType result = field;
    if (result == null) { // Primeira verificação (sem bloqueio)
        synchronized (this) {
            result = field;
            if (result == null) { // Segunda verificação (com bloqueio)
                field = result = computeFieldValue();
            }
        }
    }
    return result;
}

Enter fullscreen mode Exit fullscreen mode

5. Prática de Verificação Única (Inicialização Repetida Permitida)

  • Quando usar: Campos que podem tolerar inicializações repetidas.

Exemplo

private volatile FieldType field;

FieldType getField() {
    if (field == null) { // Verificação única
        field = computeFieldValue();
    }
    return field;
}

Enter fullscreen mode Exit fullscreen mode

6. Prática Ousada de Verificação Única

  • Quando usar: Apenas se tolerar inicializações extras e se o tipo do campo for um primitivo diferente de long ou double.

Exemplo:

private FieldType field;

FieldType getField() {
    if (field == null) { // Sem volatile
        field = computeFieldValue();
    }
    return field;
}

Enter fullscreen mode Exit fullscreen mode

Considerações Gerais

Trade-offs:

  • Inicialização preguiçosa minimiza o custo inicial, mas pode aumentar o custo de acesso ao campo.
  • Avalie com medições de desempenho.

Sincronização em Multithread:

  • Fundamental para evitar bugs graves.
  • Utilize práticas seguras (e.g., volatile, bloqueios).

Uso Preferencial:

  • Campos Estáticos: Prática da classe portadora.
  • Campos de Instância: Verificação dupla.
  • Inicialização Repetida Permitida: Verificação única.

Resumo Final

  • Inicialize normalmente sempre que possível.
  • Use inicialização preguiçosa apenas quando necessário para desempenho ou para resolver problemas de circularidade

AWS Security LIVE!

Join us for AWS Security LIVE!

Discover the future of cloud security. Tune in live for trends, tips, and solutions from AWS and AWS Partners.

Learn More

Top comments (0)

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay