Necesitamos distinguir dos aspectos de las constantes:
- nombres para valores conocidos en el momento del desarrollo, que presentamos para una mejor mantenibilidad, y
- valores que están disponibles para el compilador.
Y luego hay un tercer tipo relacionado: variables cuyo valor no cambia, es decir, nombres para un valor. La diferencia entre estas variables inmutables y una constante es cuando se determina / asigna / inicializa el valor: una variable se inicializa en tiempo de ejecución, pero el valor de una constante se conoce durante el desarrollo. Esta distinción es un poco confusa ya que un valor puede ser conocido durante el desarrollo, pero en realidad solo se crea durante la inicialización.
Pero si el valor de una constante se conoce en tiempo de compilación, entonces el compilador puede realizar cálculos con ese valor. Por ejemplo, el lenguaje Java tiene el concepto de expresiones constantes . Una expresión constante es cualquier expresión que consiste solo en literales de primitivas o cadenas, operaciones en expresiones constantes (como conversión, suma, concatenación de cadenas) y variables constantes. [ JLS §15.28 ] Una variable constante es una final
variable que se inicializa con una expresión constante. [JLS §4.12.4] Entonces, para Java, esta es una constante de tiempo de compilación:
public static final int X = 7;
Esto se vuelve interesante cuando se usa una variable constante en múltiples unidades de compilación, y luego se cambia la declaración. Considerar:
Ahora, cuando compilamos estos archivos, el B.class
bytecode declarará un campo Y = 9
porque B.Y
es una variable constante.
Pero cuando cambiamos la A.X
variable a un valor diferente (digamos X = 0
) y volvemos a compilar solo el A.java
archivo, B.Y
aún se refiere al valor anterior. Este estado A.X = 0, B.Y = 9
es inconsistente con las declaraciones en el código fuente. ¡Feliz depuración!
Esto no significa que las constantes nunca deban cambiarse. Las constantes son definitivamente mejores que los números mágicos que aparecen sin explicación en el código fuente. Sin embargo, el valor de las constantes públicas es parte de su API pública . Esto no es específico de Java, pero también ocurre en C ++ y otros lenguajes que cuentan con unidades de compilación separadas. Si cambia estos valores, deberá volver a compilar todo el código dependiente, es decir, realizar una compilación limpia.
Dependiendo de la naturaleza de las constantes, podrían haber llevado a suposiciones incorrectas por parte de los desarrolladores. Si se cambian estos valores, podrían desencadenar un error. Por ejemplo, se puede elegir un conjunto de constantes para que formen ciertos patrones de bits, por ejemplo public static final int R = 4, W = 2, X = 1
. Si se cambian para formar una estructura diferente, como el R = 0, W = 1, X = 2
código existente, como se boolean canRead = perms & R
vuelve incorrecto. ¡Y solo piense en la diversión que se produciría si Integer.MAX_VALUE
cambiaran! Aquí no hay una solución, es importante recordar que el valor de algunas constantes es realmente importante y no se puede cambiar simplemente.
Pero para la mayoría de las constantes, cambiarlas estará bien siempre que se tengan en cuenta las restricciones anteriores. Es seguro cambiar una constante cuando el significado, no el valor específico, es importante. Este es, por ejemplo, el caso de los sintonizables como BORDER_WIDTH = 2
o TIMEOUT = 60; // seconds
plantillas como API_ENDPOINT = "https://api.example.com/v2/"
, aunque podría decirse que algunos o todos deberían especificarse en los archivos de configuración en lugar de en el código.