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, lors de la compilation, une erreur constant expression required
apparaît sur chacune des 3 étiquettes de cas.
Je comprends que le compilateur a besoin de connaître l'expression au moment de la compilation pour compiler un commutateur, mais pourquoi Foo.BA_
n'est-il pas constant?
Je comprends que le compilateur a besoin que l’expression soit connue au moment de la compilation pour compiler un commutateur, mais pourquoi Foo.BA_ n’est-il pas constant?
Bien qu’ils soient constants du point de vue du code qui s’exécute après l’initialisation des champs, ils ne sont pas une constante de temps de compilation au sens requis par le JLS; voir §15.28 Expressions constantes pour une définition de ce qui est requis d'une expression constante. Ceci fait référence à §4.12.4 Variables finales qui définit une "variable constante" comme suit:
Nous appelons une variable, de type primitif ou de type String, finale et initialisée avec une expression constante au moment de la compilation (§15.28), une variable constante. Le fait qu'une variable soit ou non une variable constante peut avoir des implications en ce qui concerne l'initialisation de classe (§12.4.1), la compatibilité binaire (§13.1, §13.4.9) et l'affectation définie (§16).
Dans votre exemple, les variables Foo.BA * n'ont pas d'initialiseurs et ne peuvent donc pas être qualifiées de "variables constantes". La solution est simple. changez les déclarations de variable Foo.BA * pour que les initialiseurs soient des expressions constantes au moment de la compilation.
Dans d'autres exemples (où les initialiseurs sont déjà des expressions constantes au moment de la compilation), la déclaration de la variable en tant que final
peut être ce qui est nécessaire.
Et, bien sûr, vous pouvez modifier votre code pour utiliser une constante enum
plutôt que int
, bien que cela pose un autre problème. Si vous utilisez un enum
dans un switch
, vous devez inclure un cas default
, même si vous avez case
pour chaque valeur connue de enum
; voir Pourquoi la valeur par défaut est-elle requise pour un commutateur sur une énumération dans ce code?
Vous obtenez Expression constante requise parce que vous avez laissé les valeurs de vos constantes. Essayer:
public abstract class Foo {
...
public static final int BAR=0;
public static final int BAZ=1;
public static final int BAM=2;
...
}
J'ai eu cette erreur sur Android, et ma solution était juste d'utiliser:
public static final int TAKE_PICTURE = 1;
au lieu de
public static int TAKE_PICTURE = 1;
Parce que ce ne sont pas des constantes de temps de compilation. Considérons le code valide suivant:
public static final int BAR = new Random().nextInt();
Vous pouvez uniquement connaître la valeur de BAR
au moment de l'exécution.
Vous pouvez utiliser une énumération comme dans cet exemple:
public class MainClass {
enum Choice { Choice1, Choice2, Choice3 }
public static void main(String[] args) {
Choice ch = Choice.Choice1;
switch(ch) {
case Choice1:
System.out.println("Choice1 selected");
break;
case Choice2:
System.out.println("Choice2 selected");
break;
case Choice3:
System.out.println("Choice3 selected");
break;
}
}
}
Source: Instruction switch avec enum
Cela a été répondu il y a longtemps et probablement sans objet, mais juste au cas où… __. Lorsque j'ai été confronté à ce problème, j'ai simplement utilisé une instruction if
au lieu de switch
, le problème a été résolu . et probablement pas la "bonne" solution, mais dans mon cas c'était juste suffisant.
Parfois, la variable variable peut aussi commettre cette erreur, par exemple:
switch(view.getTag()) {//which is an Object type
case 0://will give compiler error that says Constant expression required
//...
}
Pour résoudre ce problème, vous devez convertir la variable en int (dans ce cas). Alors:
switch((int)view.getTag()) {//will be int
case 0: //No Error
//...
}
Dans mon cas, je recevais cette exception parce que
switch (tipoWebServ) {
case VariablesKmDialog.OBTENER_KM:
resultObtenerKm(result);
break;
case var.MODIFICAR_KM:
resultModificarKm(result);
break;
}
dans le second cas, j'appelais la constante de l'instance var.MODIFICAR_KM:
mais je devrais utiliser VariablesKmDialog.OBTENER_KM
directement à partir de la classe.
Je vous recommande d'utiliser des enums :)
Regarde ça:
public enum Foo
{
BAR("bar"),
BAZ("baz"),
BAM("bam");
private final String description;
private Foo(String description)
{
this.description = description;
}
public String getDescription()
{
return description;
}
}
Ensuite, vous pouvez l'utiliser comme ceci:
System.out.println(Foo.BAR.getDescription());
Vous avez cette erreur dans Android en faisant quelque chose comme ça:
roleSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (parent.getItemAtPosition(position)) {
case ADMIN_CONSTANT: //Threw the error
}
malgré déclarer une constante:
public static final String ADMIN_CONSTANT= "Admin";
J'ai résolu le problème en changeant mon code pour ceci:
roleSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String selectedItem = String.valueOf(parent.getItemAtPosition(position));
switch (selectedItem) {
case ADMIN_CONSTANT:
}