Entendo que o compilador precisa que a expressão seja conhecida no momento da compilação para compilar um switch, mas por que o Foo.BA_ não é constante?
Embora sejam constantes da perspectiva de qualquer código que seja executado após a inicialização dos campos, eles não são uma constante de tempo de compilação no sentido exigido pelo JLS; consulte §15.28 Expressões constantes para a especificação de uma expressão constante 1 . Isso se refere a §4.12.4 Variáveis finais, que define uma "variável constante" da seguinte maneira:
Chamamos uma variável, do tipo primitivo ou do tipo String, que é final e inicializada com uma expressão constante em tempo de compilação (§15.28) como variável constante. Se uma variável é uma variável constante ou não, pode ter implicações em relação à inicialização de classe (§12.4.1), compatibilidade binária (§13.1, §13.4.9) e atribuição definida (§16).
No seu exemplo, as variáveis Foo.BA * não possuem inicializadores e, portanto, não se qualificam como "variáveis constantes". A correção é simples; altere as declarações da variável Foo.BA * para ter inicializadores que são expressões constantes em tempo de compilação.
Em outros exemplos (onde os inicializadores já são expressões constantes em tempo de compilação), declarar a variável como final
pode ser o necessário.
Você pode alterar seu código para usar um enum
int
constantes em vez de constantes, mas isso traz outras restrições diferentes:
1 - As restrições de expressão constante podem ser resumidas da seguinte forma. Expressões constantes a) pode utilizar os tipos de primitivas e String
única, b) permitir que primárias que são literais (aparte null
) e variáveis constantes única, c) permitir que expressões constantes possivelmente parenthesised como subexpress~oes, d) permitir que os operadores excepto para operadores de atribuição, ++
, --
ou instanceof
, e e) permitir a conversão de tipos para tipos primitivos ouString
apenas.
Note que isto não inclui qualquer forma de método ou lambda chamadas, new
, .class
. .length
ou assinatura de matriz. Além disso, qualquer uso de valores de matriz, enum
valores, valores de tipos de invólucros primitivos, boxe e unboxing são todos excluídos por causa de a).