Entiendo que el compilador necesita que la expresión se conozca en el momento de la compilación para compilar un conmutador, pero ¿por qué no es constante Foo.BA_?
Si bien son constantes desde la perspectiva de cualquier código que se ejecute después de que se hayan inicializado los campos, no son una constante de tiempo de compilación en el sentido requerido por JLS; vea §15.28 Expresiones constantes para la especificación de una expresión constante 1 . Esto se refiere a §4.12.4 Variables finales que define una "variable constante" de la siguiente manera:
Llamamos a una variable, de tipo primitivo o tipo String, que es final e inicializada con una expresión constante en tiempo de compilación (§15.28) una variable constante. Si una variable es una variable constante o no, puede tener implicaciones con respecto a la inicialización de la clase (§12.4.1), la compatibilidad binaria (§13.1, §13.4.9) y la asignación definida (§16).
En su ejemplo, las variables Foo.BA * no tienen inicializadores y, por lo tanto, no califican como "variables constantes". La solución es simple; cambie las declaraciones de variables Foo.BA * para tener inicializadores que sean expresiones constantes en tiempo de compilación.
En otros ejemplos (donde los inicializadores ya son expresiones constantes en tiempo de compilación), declarar la variable como final
puede ser lo que se necesita.
Puede cambiar su código para usar una en enum
lugar de int
constantes, pero eso trae otro par de restricciones diferentes:
1 - Las restricciones de expresión constante se pueden resumir de la siguiente manera. Las expresiones constantes a) pueden usar tipos primitivos y String
solo, b) permitir primarios que sean literales (aparte de null
) y solo variables constantes, c) permitir expresiones constantes posiblemente entre paréntesis como subexpresiones, d) permitir operadores excepto operadores de asignación ++
, --
o instanceof
, y e) permitir conversiones de tipos a tipos primitivos o String
solo.
Tenga en cuenta que esto no incluye ningún tipo de método o lambda llamadas, new
, .class
. .length
o suscripciones de matriz. Además, cualquier uso de valores de matriz, enum
valores, valores de tipos de envoltorio primitivo, boxeo y unboxing están excluidos debido a a).