A importância de utilizar atributos final no Java

Por Gaspar Barancelli Junior em 04 de abril de 2024

O Java é uma linguagem de programação orientada a objetos que permite o uso de variáveis e atributos que podem ser alterados durante a execução do programa. No entanto, em certos casos, é necessário garantir que determinada variável ou atributo não sofra alterações após sua inicialização. Para isso, é importante utilizar o modificador final.

O atributo final é uma propriedade que garante que a variável ou atributo seja inicializado apenas uma vez e que seu valor não possa ser modificado posteriormente. Essa característica é muito importante em códigos que envolvem concorrência, ou seja, em situações em que diferentes threads do programa podem acessar e alterar os mesmos dados simultaneamente.

Quando há concorrência no código, é possível que duas ou mais threads acessem e tentem modificar o mesmo atributo ou variável ao mesmo tempo. Isso pode causar inconsistências e erros difíceis de detectar e corrigir. Utilizar o atributo final pode evitar esses problemas, pois garante que o valor do atributo não seja modificado por nenhuma thread após sua inicialização.

Um exemplo de utilização do atributo final em código que envolve concorrência é em classes que possuem objetos compartilhados por várias threads. Ao utilizar o atributo final para definir a referência a esse objeto compartilhado, é possível garantir que todas as threads irão utilizar a mesma referência, evitando problemas de inconsistência nos dados.

Além disso, utilizar atributos final também pode melhorar a performance do código. Isso ocorre porque a JVM (Java Virtual Machine) pode realizar otimizações no código, como a eliminação de código redundante, ao identificar que determinada variável ou atributo não será modificado após sua inicialização.

É importante lembrar que o atributo final deve ser utilizado com cautela e apenas em situações em que a imutabilidade do atributo ou variável é essencial para garantir a correta execução do código. Caso contrário, seu uso pode tornar o código mais difícil de entender e manter.

Exemplos

1. Atributos final de classe

Atributos declarados como final em uma classe não podem ser modificados depois que foram inicializados, mesmo que a classe tenha métodos que possam alterar outros atributos. Esses atributos também podem ser acessados a partir de outros objetos sem a necessidade de instanciar a classe.

public class ExemploFinal {
  public static final double PI = 3.14;
  private final String nome;

  public ExemploFinal(String nome) {
    this.nome = nome;
  }

  public String getNome() {
    return nome;
  }
}

Nesse exemplo, PI é um atributo final que pode ser acessado diretamente sem precisar instanciar a classe ExemploFinal. O atributo nome é outro exemplo de um atributo final, mas ele só pode ser inicializado no construtor e depois não pode mais ser modificado.

2. Argumentos final de método

Ao utilizar a palavra-chave final em um argumento de método, você garante que ele não será modificado dentro do corpo do método. Isso pode ajudar a evitar bugs em código que depende do valor desses argumentos.

public void exibirMensagemFinal(final String mensagem) {
  System.out.println(mensagem);
}

Nesse exemplo, o argumento mensagem é declarado como final para garantir que o valor dela não seja alterado dentro do método exibirMensagemFinal.

3. Métodos final

A palavra-chave final também pode ser utilizada em métodos para evitar que eles sejam sobrescritos por subclasses. Isso pode ser útil em classes que não devem ter seus métodos alterados por outras classes que herdam dela.

public class ExemploFinal {
  public final void exibirMensagem() {
    System.out.println("Mensagem final.");
  }
}

public class ExemploSubclasse extends ExemploFinal {
  // Tentativa de sobrescrever o método exibirMensagem()
  // resultará em erro de compilação.
}

Nesse exemplo, o método exibirMensagem é declarado como final, então ele não pode ser sobrescrito por subclasses da classe ExemploFinal.

4. Classes final

Ao utilizar a palavra-chave final em uma classe, você garante que ela não pode ser estendida por outras classes. Isso pode ser útil em classes que não devem ser modificadas ou estendidas por outras classes.

public final class ExemploFinal {
  public void exibirMensagem() {
    System.out.println("Mensagem final.");
  }
}

public class ExemploSubclasse extends ExemploFinal {
  // Tentativa de estender a classe ExemploFinal
  // resultará em erro de compilação.
}

Nesse exemplo, a classe ExemploFinal é declarada como final, então ela não pode ser estendida por outras classes como ExemploSubclasse.

Conclusão

Em resumo, utilizar o atributo final no Java é uma boa prática de programação que pode melhorar a qualidade e a performance do código, especialmente em situações de concorrência. Porém, seu uso deve ser ponderado e limitado apenas a casos em que a imutabilidade do atributo ou variável é essencial para o funcionamento correto do programa.

// Compartilhe esse Post