Donc, je travaille sur cette classe qui a quelques constantes statiques:
public abstract class Foo {
...
public static final int BAR;
public static final int BAZ;
public static final int BAM;
...
}
Ensuite, je voudrais un moyen d'obtenir une chaîne pertinente basée sur la constante:
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";
}
}
Cependant, lorsque je compile, j'obtiens une constant expression required
erreur sur chacune des 3 étiquettes de cas.
Je comprends que le compilateur a besoin que l'expression soit connue au moment de la compilation pour compiler un commutateur, mais pourquoi n'est-elle pas Foo.BA_
constante?
java
compile-time-constant
Austin Hyde
la source
la source
public static final int
s sont dispersés dans tout le JDK, c'est donc ce que j'ai choisi.Réponses:
Bien qu'ils soient constants du point de vue de tout code qui s'exécute après que les champs ont été initialisés, ils ne sont pas une constante de temps de compilation au sens requis par le JLS; voir §15.28 Expressions constantes pour la spécification d'une expression constante 1 . Ceci fait référence au §4.12.4 Variables finales qui définit une "variable constante" comme suit:
Dans votre exemple, les variables Foo.BA * n'ont pas d'initialiseurs et ne sont donc pas qualifiées de "variables constantes". Le correctif est simple; changez les déclarations de variable Foo.BA * pour avoir des initialiseurs qui sont des expressions constantes à la compilation.
Dans d'autres exemples (où les initialiseurs sont déjà des expressions constantes au moment de la compilation), déclarer la variable selon les
final
besoins.Vous pouvez modifier votre code pour utiliser un
enum
plutôt que desint
constantes, mais cela apporte un autre couple de restrictions différentes:default
cas, même si vous avezcase
pour chaque valeur connue deenum
; voir Pourquoi la valeur par défaut est-elle requise pour un commutateur sur une énumération?case
étiquettes doivent toutes être desenum
valeurs explicites , pas des expressions qui s'évaluent enenum
valeurs.1 - Les restrictions d'expression constante peuvent être résumées comme suit. Les expressions constantes a) peuvent utiliser des types primitifs et
String
seulement, b) autoriser les primaires qui sont des littéraux (en dehors denull
) et des variables constantes uniquement, c) autoriser les expressions constantes éventuellement entre parenthèses comme des sous-expressions, d) autoriser les opérateurs sauf pour les opérateurs d'affectation++
,--
ouinstanceof
, et e) autoriser les transtypages de types en types primitifs ouString
uniquement.Notez que cela ne comprend aucune forme d'appels de méthode ou lambda,
new
,.class
..length
ou indice de tableau. En outre, toute utilisation de valeurs de tableau, deenum
valeurs, de valeurs de types d'encapsuleurs primitifs, de mise en boîte et de déballage sont toutes exclues en raison de a).la source
Vous obtenez l' expression constante requise car vous avez laissé les valeurs hors de vos constantes. Essayer:
la source
J'ai eu cette erreur sur Android, et ma solution consistait simplement à utiliser:
au lieu de
la source
Parce que ce ne sont pas des constantes de temps de compilation. Considérez le code valide suivant:
Vous ne pouvez connaître la valeur de
BAR
qu'en runtime.la source
public static final int BAR = new Random().nextInt()
travailler?new Random().nextInt()
renvoyer les mêmes valeurs?Vous pouvez utiliser une énumération comme dans cet exemple:
Source: instruction Switch avec enum
la source
enum Codes { CODE_A(1), CODE_B(2); private mCode; Codes(int i) { mCode = i; } public int code() { return mCode; } }
<br/> Quand j'essaye d'utiliser l'énumération dans le commutateur, j'obtiens la même erreur ... <br/>switch(field) { case Codes.CODE_A.code() : // do stuffs.. ; }
<br/> Il est possible de résoudre le problème?Cela a été répondu il y a longtemps et probablement pas pertinent, mais juste au cas où. Lorsque j'ai été confronté à ce problème, j'ai simplement utilisé une
if
déclaration au lieu deswitch
, cela a résolu l'erreur. C'est bien sûr une solution de contournement et probablement pas la «bonne» solution, mais dans mon cas, c'était juste suffisant.la source
switch
c'est généralement plus rapide que longif-else
, carswitch
ne vérifiez la condition qu'une seule fois , alors qu'avecif-else
vous devrez peut-être vérifier toutes les conditions avant de trouver la bonne.Parfois, la variable switch peut également faire cette erreur, par exemple:
Pour résoudre, vous devez convertir la variable en int (dans ce cas). Alors:
la source
Vous avez cette erreur dans Android en faisant quelque chose comme ceci:
malgré la déclaration d'une constante:
public static final String ADMIN_CONSTANT= "Admin";
J'ai résolu le problème en modifiant mon code comme suit:
la source
Dans mon cas, j'obtenais cette exception car
dans le second cas, j'appelais la constante depuis l'instance
var.MODIFICAR_KM:
mais je devrais l'utiliserVariablesKmDialog.OBTENER_KM
directement depuis la classe.la source
Si vous l'utilisez dans un boîtier de commutateur, vous devez obtenir le type d'énumération avant même de brancher cette valeur dans le commutateur. Par exemple :
Et l'énumération est comme:
la source
Le code ci-dessous est explicite, nous pouvons utiliser une énumération avec un cas de commutateur:
Basé sur les valeurs de classe de l'énumération peuvent être mappées:
J'espère que ça aide :)
la source
Je recommande d'utiliser la manière suivante:
la source
private Animal(String name) { this.name = name; }
Je vous recommande d'utiliser les énumérations :)
Regarde ça:
Ensuite, vous pouvez l'utiliser comme ceci:
la source