Há muitos usos para a variável final
. Aqui estão apenas alguns
Constantes Finais
public static class CircleToolsBetter {
public final static double PI = 3.141;
public double getCircleArea(final double radius) {
return (Math.pow(radius, 2) * PI);
}
}
Isso pode ser usado para outras partes dos seus códigos ou acessado por outras classes, dessa forma, se você alterar o valor, não precisará alterá-los um por um.
Variáveis finais
public static String someMethod(final String environmentKey) {
final String key = "env." + environmentKey;
System.out.println("Key is: " + key);
return (System.getProperty(key));
}
}
Nesta classe, você cria uma variável final com escopo que adiciona um prefixo ao parâmetro environmentKey. Nesse caso, a variável final é final apenas dentro do escopo de execução, que é diferente a cada execução do método. Cada vez que o método é inserido, a final é reconstruída. Assim que é construído, não pode ser alterado durante o escopo da execução do método. Isso permite que você corrija uma variável em um método pela duração do método. ver abaixo:
public class FinalVariables {
public final static void main(final String[] args) {
System.out.println("Note how the key variable is changed.");
someMethod("JAVA_HOME");
someMethod("ANT_HOME");
}
}
Constantes Finais
public double equation2Better(final double inputValue) {
final double K = 1.414;
final double X = 45.0;
double result = (((Math.pow(inputValue, 3.0d) * K) + X) * M);
double powInputValue = 0;
if (result > 360) {
powInputValue = X * Math.sin(result);
} else {
inputValue = K * Math.sin(result); // <= Compiler error
}
Isso é especialmente útil quando você tem realmente longas linhas de códigos e gera erros de compilador para que você não encontre erros de lógica / negócios quando alguém acidentalmente altera variáveis que não devem ser alteradas.
Coleções finais
Caso diferente, quando falamos de coleções, você precisa defini-las como não modificáveis.
public final static Set VALID_COLORS;
static {
Set temp = new HashSet( );
temp.add(Color.red);
temp.add(Color.orange);
temp.add(Color.yellow);
temp.add(Color.green);
temp.add(Color.blue);
temp.add(Color.decode("#4B0082")); // indigo
temp.add(Color.decode("#8A2BE2")); // violet
VALID_COLORS = Collections.unmodifiableSet(temp);
}
caso contrário, se você não definir como modificável:
Set colors = Rainbow.VALID_COLORS;
colors.add(Color.black); // <= logic error but allowed by compiler
Classes finais e métodos finais não podem ser estendidos ou substituídos, respectivamente.
EDIT: ENDEREÇO AO PROBLEMA DA CLASSE FINAL RELATIVO AO ENCAPSULAMENTO:
Existem duas maneiras de fazer uma aula final. O primeiro é usar a palavra-chave final na declaração de classe:
public final class SomeClass {
// . . . Class contents
}
A segunda maneira de finalizar uma classe é declarar todos os seus construtores como privados:
public class SomeClass {
public final static SOME_INSTANCE = new SomeClass(5);
private SomeClass(final int value) {
}
Marcá-lo como final evita o problema se descobrir que é realmente um final, para demonstrar o olhar para essa classe de teste. parece público à primeira vista.
public class Test{
private Test(Class beanClass, Class stopClass, int flags)
throws Exception{
// . . . snip . . .
}
}
Infelizmente, como o único construtor da classe é privado, é impossível estender essa classe. No caso da classe Teste, não há razão para que a classe seja final. A classe Test é um bom exemplo de como as classes finais implícitas podem causar problemas.
Portanto, você deve marcá-lo como final quando implicitamente tornar uma classe final, tornando seu construtor privado.