Em Java tudo o que é final (static ou não, tanto faz para o que direi, não confundam) é constante, mas isso está sujeito a algumas regras…
Se for variável primitiva, o valor determinado é fixo e imutável. Ex:
Esse número é 10 pra sempre (enquanto a instância da classe durar, claro).
Se for um objeto (incluindo array, String, Wrappers como Integer e Double… tudo o que não é variável primitiva em Java é objeto), a instância associada à variável final não pode ser trocada, mas os valores internos da instância podem. Ex:
Vejam a classe:
public class Pessoa{
public String nome;
public int idade;
public Pessoa(String nome, int idade){
this.nome = nome;
this.idade = idade;
}
}
Vejam as variáveis finais:
private final Pessoa p = new Pessoa("Carlos", 21);
private final Integer num = Integer.valueOf(10);
Ambos são objetos. o tipo Integer é uma classe Wrapper, que “empacota” / “embrulha” um valor primitivo int e ainda oferece métodos auxiliares para processamento do dado. Se eu quiser posso modificar os valores contidos nesses objetos. Instanciadas essas constantes, isso é legal:
Vejam que não mudei a instância, só o valor de um atributo.
Isso é ilegal:
Já que tenta mudar a instância de Pessoa associada à constante p.
Resumindo: mesmo um array constante como esse:
Pode ter os seus valores alterados, já que esse array é um vetor de dados do tipo int, portanto é um objeto.