Wir müssen zwei Aspekte von Konstanten unterscheiden:
- Namen für Werte, die zur Entwicklungszeit bekannt waren und die wir zur besseren Wartbarkeit einführen, und
- Werte, die dem Compiler zur Verfügung stehen.
Und dann gibt es eine verwandte dritte Art: Variablen, deren Wert sich nicht ändert, dh Namen für einen Wert. Der Unterschied zwischen diesen unveränderlichen Variablen und einer Konstanten besteht darin, dass der Wert bestimmt / zugewiesen / initialisiert wird: Eine Variable wird zur Laufzeit initialisiert, der Wert einer Konstanten ist jedoch während der Entwicklung bekannt. Diese Unterscheidung ist etwas trübe, da ein Wert möglicherweise während der Entwicklung bekannt ist, aber tatsächlich nur während der Initialisierung erstellt wird.
Wenn der Wert einer Konstante jedoch zur Kompilierungszeit bekannt ist, kann der Compiler Berechnungen mit diesem Wert durchführen. Zum Beispiel hat die Java-Sprache das Konzept der konstanten Ausdrücke . Ein konstanter Ausdruck ist ein Ausdruck, der nur aus Literalen von Primitiven oder Zeichenfolgen, Operationen für konstante Ausdrücke (z. B. Casting, Addition, Zeichenfolgenverkettung) und konstanten Variablen besteht. [ JLS §15.28 ] Eine konstante Variable ist eine final
Variable, die mit einem konstanten Ausdruck initialisiert wird. [JLS §4.12.4] Für Java ist dies eine Konstante zur Kompilierungszeit:
public static final int X = 7;
Dies wird interessant, wenn eine konstante Variable in mehreren Kompilierungseinheiten verwendet wird und dann die Deklaration geändert wird. Erwägen:
Wenn wir diese Dateien kompilieren B.class
, deklariert der Bytecode ein Feld, Y = 9
da B.Y
es sich um eine konstante Variable handelt.
Wenn wir jedoch die A.X
Variable auf einen anderen Wert ändern (z. B. X = 0
) und nur die A.java
Datei neu kompilieren , wird B.Y
weiterhin auf den alten Wert verwiesen. Dieser Status A.X = 0, B.Y = 9
stimmt nicht mit den Deklarationen im Quellcode überein. Viel Spaß beim Debuggen!
Dies bedeutet nicht, dass Konstanten niemals geändert werden sollten. Konstanten sind definitiv besser als magische Zahlen, die ohne Erklärung im Quellcode vorkommen. Doch der Wert ist der öffentlichen Konstanten Teil Ihrer öffentlichen API . Dies ist nicht spezifisch für Java, tritt jedoch auch in C ++ und anderen Sprachen mit separaten Kompilierungseinheiten auf. Wenn Sie diese Werte ändern, müssen Sie den gesamten abhängigen Code neu kompilieren, dh eine Neukompilierung durchführen.
Abhängig von der Art der Konstanten können sie zu falschen Annahmen der Entwickler geführt haben. Wenn diese Werte geändert werden, können sie einen Fehler auslösen. Beispielsweise könnte ein Satz von Konstanten so gewählt werden, dass sie bestimmte Bitmuster bilden, z public static final int R = 4, W = 2, X = 1
. Wenn diese geändert werden, um eine andere Struktur wie zu bilden, wird R = 0, W = 1, X = 2
vorhandener Code wie boolean canRead = perms & R
falsch. Und denken Sie nur an den Spaß, der sich daraus ergeben würde, wenn Sie sich Integer.MAX_VALUE
ändern würden! Hier gibt es keine Fehlerbehebung. Es ist nur wichtig zu wissen, dass der Wert einiger Konstanten wirklich wichtig ist und nicht einfach geändert werden kann.
Aber für die Mehrheit der Konstanten ist das Ändern in Ordnung, solange die obigen Einschränkungen berücksichtigt werden. Eine Konstante kann sicher geändert werden, wenn die Bedeutung und nicht der spezifische Wert wichtig sind. Dies ist z. B. der Fall für Tunables wie BORDER_WIDTH = 2
oder TIMEOUT = 60; // seconds
oder Vorlagen wie API_ENDPOINT = "https://api.example.com/v2/"
- obwohl einige oder alle davon möglicherweise in Konfigurationsdateien und nicht in Code angegeben werden sollten.