Ich arbeite also an dieser Klasse, die einige statische Konstanten hat:
public abstract class Foo {
...
public static final int BAR;
public static final int BAZ;
public static final int BAM;
...
}
Dann möchte ich einen Weg finden, einen relevanten String basierend auf der Konstante zu erhalten:
public static String lookup(int constant) {
switch (constant) {
case Foo.BAR: return "bar";
case Foo.BAZ: return "baz";
case Foo.BAM: return "bam";
default: return "unknown";
}
}
Beim Kompilieren wird jedoch constant expression required
auf jedem der drei Falletiketten eine Fehlermeldung angezeigt.
Ich verstehe, dass der Compiler den Ausdruck benötigt, der zur Kompilierungszeit bekannt sein muss, um einen Switch zu kompilieren, aber warum ist er nicht Foo.BA_
konstant?
java
compile-time-constant
Austin Hyde
quelle
quelle
public static final int
s sind im gesamten JDK verstreut, also habe ich mich dafür entschieden.Antworten:
Während sie aus der Sicht eines Codes konstant sind, der nach der Initialisierung der Felder ausgeführt wird, sind sie keine Kompilierungszeitkonstante im Sinne des JLS. siehe §15.28 Konstante Ausdrücke für die Angabe eines konstanten Ausdrucks 1 . Dies bezieht sich auf §4.12.4 Endvariablen, der eine "konstante Variable" wie folgt definiert:
In Ihrem Beispiel haben die Foo.BA * -Variablen keine Initialisierer und gelten daher nicht als "konstante Variablen". Das Update ist einfach; Ändern Sie die Foo.BA * -Variablendeklarationen so, dass Initialisierer Konstantenausdrücke zur Kompilierungszeit sind.
In anderen Beispielen (in denen die Initialisierer bereits Konstantenausdrücke zur Kompilierungszeit sind) wird die Variable als
final
erforderlich deklariert .Sie könnten Ihren Code so ändern, dass er eine Konstante
enum
anstelle vonint
Konstanten verwendet. Dies bringt jedoch noch einige andere Einschränkungen mit sich:default
Fall einschließen , auch wenn Siecase
für jeden bekannten Wert derenum
; Siehe Warum ist die Standardeinstellung für einen Schalter in einer Aufzählung erforderlich?case
Beschriftungen müssen alle expliziteenum
Werte sein, keine Ausdrücke, die zuenum
Werten ausgewertet werden.1 - Die Einschränkungen für konstante Ausdrücke können wie folgt zusammengefasst werden. Konstante Ausdrücke a) können primitive Typen verwenden und
String
nur, b) Primäre zulassen, die Literale (außernull
) und nur konstante Variablen sind, c) konstante Ausdrücke zulassen, die möglicherweise als Unterausdrücke in Klammern stehen, d) Operatoren außer Zuweisungsoperatoren zulassen++
,--
oderinstanceof
, und e) Typumwandlungen für primitive Typen oderString
nur zulassen .Beachten Sie, dass dies keine Form von Verfahren oder Lambda - Anrufe enthält,
new
,.class
..length
oder Array-Subskription. Darüber hinaus ist die Verwendung von Array-Werten,enum
Werten, Werten primitiver Wrapper-Typen, Boxing und Unboxing aufgrund von a) ausgeschlossen.quelle
Sie erhalten den Ausdruck Konstante erforderlich, weil Sie die Werte von Ihren Konstanten weggelassen haben. Versuchen:
quelle
Ich habe diesen Fehler auf Android erhalten und meine Lösung war nur zu verwenden:
anstatt
quelle
Weil dies keine Kompilierungszeitkonstanten sind. Betrachten Sie den folgenden gültigen Code:
Sie können den Wert von nur
BAR
zur Laufzeit kennen.quelle
public static final int BAR = new Random().nextInt()
funktionieren?new Random().nextInt()
die gleichen Werte zurückgeben?Sie können eine Aufzählung wie in diesem Beispiel verwenden:
Quelle: Switch-Anweisung mit Aufzählung
quelle
enum Codes { CODE_A(1), CODE_B(2); private mCode; Codes(int i) { mCode = i; } public int code() { return mCode; } }
<br/> Wenn ich versuche, die Aufzählung im Switch zu verwenden, wird der gleiche Fehler angezeigt ... <br/>switch(field) { case Codes.CODE_A.code() : // do stuffs.. ; }
<br/> Ist es möglich, das Problem zu lösen?Dies wurde vor Ewigkeiten beantwortet und ist wahrscheinlich nicht relevant, aber nur für den Fall. Als ich mit diesem Problem konfrontiert wurde, habe ich einfach eine
if
Aussage verwendet, anstattswitch
den Fehler zu beheben. Es ist natürlich eine Problemumgehung und wahrscheinlich nicht die "richtige" Lösung, aber in meinem Fall war es gerade genug.quelle
switch
im Allgemeinen schneller als lang istif-else
, daswitch
Sie den Zustand nur einmal überprüfen müssen , währendif-else
Sie möglicherweise alle Zustände überprüfen müssen, bevor Sie den richtigen finden.Manchmal kann die Schaltvariable auch diesen Fehler machen, zum Beispiel:
Zum Lösen sollten Sie die Variable in int umwandeln (in diesem Fall). So:
quelle
Ich habe diesen Fehler in Android erhalten, als ich so etwas gemacht habe:
trotz der Angabe einer Konstanten:
public static final String ADMIN_CONSTANT= "Admin";
Ich habe das Problem behoben, indem ich meinen Code folgendermaßen geändert habe:
quelle
In meinem Fall bekam ich diese Ausnahme, weil
Im zweiten Fall habe ich die Konstante aus der Instanz aufgerufen,
var.MODIFICAR_KM:
aber ich sollte sieVariablesKmDialog.OBTENER_KM
direkt aus der Klasse verwenden.quelle
Wenn Sie es in einem Switch-Gehäuse verwenden, müssen Sie den Typ der Aufzählung abrufen, bevor Sie diesen Wert in den Switch einstecken. Zum Beispiel :
Und die Aufzählung ist wie:
quelle
Der folgende Code ist selbsterklärend. Wir können eine Aufzählung mit einem Schaltergehäuse verwenden:
Basierend auf den Klassenwerten kann die Aufzählung zugeordnet werden:
Ich hoffe es hilft :)
quelle
Ich empfehle folgende Methode:
quelle
private Animal(String name) { this.name = name; }
Ich empfehle dir, Aufzählungen zu verwenden :)
Überprüfen Sie dies heraus:
Dann können Sie es so verwenden:
quelle