Probleme switch enum

Hey Leute,

ih möchte einen switch mit einem Enum machen. Mein Problem ist, dass ich :

// int Wert vom Benutzer eingelesen
switch(int Wert) {
case:  Hund.PUDEL.ordinal();
...

}

einen int Wert switchen möchte und dann über ordinal überprüfen will

Warum zeigt er die Fehlermeldung “case expressions must be constant expressions” ?
Würde das auch evtl. anders gehen?

mfg Over

Warum über ordinal()? OK, wenn der Eingabewert aus legacy-Gründen eben ein int ist, muss das wohl sein, aber ansonsten sollte “Wert” eben direkt Hund.PUDEL oder so sein.

Wenn’s ein int sein MUSS, würde es theoretisch gehen, mit diesem int auf den Array zugreifen, der von theEnum.values() zurückgeliefert wird, aber … ein bißchen suspekt ist das schon…

Hallo,
ich würd ja gern verstehen was du willst,
vielleicht wäre etwas mehr code von Vorteil.
Wo soll denn der Code stehen, denn du da gepostet hast?
case : ???
Ich denk mal, der Compiler stört sich schon daran
Wenn da stehen würde case 1: … ;
Keine Ahnung was das Hund.Pudel.ordinal(); da tun soll…

Marco hat das ganze schon super erfasst! Aber wieso kommt dann bei mir ein Fehler?
Der Input muss leider als int sein deshalb wird der int geswitcht und über ordinal darauf zugeriffen…
Der Code ist eher pseudo :smiley:

danke schon einmal!

Tja, wer hat es gesagt, wir sind keine Hellseher.
Wenn das bisschen Code noch nicht einmal echter Code ist, dann weiss ich woher der Fehler kommt.
Es liegt daran, dass dein Code ist falsch ist :o)

Fasching hat schon begonnen, gell…

So in etwa sieht der Code der Klasse aus. Der Code im enum ist ja mehr oder weniger klar

int x= IOTools.readInt();
switch(x) {

case Hund.PUDEL.ordinal() : 
...
case Hund.SCHAEFERHUND.ordinal(): // Error case expressions must be constant expressions
...

Ja, hm, sagte doch Marco schon…
Mach dir n Array von den Enums und check es damit aus, mit .ordinal() wird das wohl nix.

vielleicht könntest du auch deine Enum etwas modifizieren und die Switch-Variable zu einer Enum umwandeln, etwa so

    EnumValue1,
    EnumValue2;

    public static MyEnum fromInteger(int x) {
        switch(x) {
        case 0:
            return EnumValue1;
        case 1:
            return EnumValue2;
        }
        return null;
    }
}```
(bei stackoverflow abgekupfert)

Wie wär’s damit:```int x= IOTools.readInt();
switch(Hund.values[x]) {

case Hund.PUDEL :

case Hund.SCHAEFERHUND: ```
bye
TT

Von mir aus, dachte da wird jedes mal n Array angelegt, was vielleicht suboptimal sein könnte… und
.values()[x] , ähm, was ist , wenn x nicht im gültigen Bereich liegt ?

[quote=pappawinni]Von mir aus, dachte da wird jedes mal n Array angelegt, was vielleicht suboptimal sein könnte…[/quote]selbst wenn… Der GC kümmert sich drum.

[quote=pappawinni;106619].values()[x] , ähm, was ist , wenn x nicht im gültigen Bereich liegt ?[/quote]Dann haben wir eine bisher unbekannte Rasse entdeckt und bekommen die Nobel-Preis für Biologie…

IMHO ist die resultierende [JAPI]IndexArraysOutOfBoundsException[/JAPI] durch aus akzeptabel.

bye
TT

Das ganze ist doch Käse: Warum die Information über die Enum im Sourcecode selbst nochmal abbilden in switch-Klauseln? Schlecht zu warten, fehleranfällig.

Als ob es da keine Möglichkeiten in Java gäbe. Notfalls eine Map<Integer,CodeFuerSpeziellesEnumObjekt>, was besseres gibt es sicher.

Frage: was passiert in den case-Blöcken? Kann man den Code nicht woanders unterbringen?

Die erste Frage ist doch aber wieso geht der case über ordinal() nicht?
Wenn ich Hund.values()[x] in die switch Klausel mache zeigt mir Eclipse keine Fehler mehr an es komnt aber zu welchen sobald das Programm läuft. Ausführlich Fehlerbeschreibung kann ich heute Abend liefern, muss gerade leider vom Handy aus schreiben

[QUOTE=Overskill]Die erste Frage ist doch aber wieso geht der case über ordinal() nicht?
[/QUOTE]

das nennt sich compile time constant

Java switch statement: Constant expression required, but it IS constant - Stack Overflow

java - why case constant must be compile time constant in switch - Stack Overflow

für Enum ist nur das saubere Enum-switch selber manuell zugelassen,
theoretisch wäre es vielleicht auch möglich, das angegebene Beispiel im Compiler zuzulassen, dürfte letztlich nicht viel anders werden,
aber dann wäre das Dilemma, ob man auch Mischformen zulässt:

        final int h = 5;
        final int q = h * 3 / 3;
        switch (k)
        {
            case h:  // double case
                System.out.println("test");
                break;
            case h * 2: // ok wie auch andere Rechnungen
                System.out.println("test");
                break;
            case q: // double case
                break;
            default:
                break;
        }

der Compiler rechnet hier mit voller Genauigkeit alles aus, was über mehrere Variablen compile-konstant zu rechnen ist,
und verbietet zwei case mit gleichen Werten, dazu könnte es mit unbekannten ordinal() aus Enums auch kommen

Auswege gibt es immer, so wie eine kompilierte Klasse mit einem bestimmten Enum-Wert zur Laufzeit einen Fehler wirft,
falls der Wert dann (aus einer separat kompilierten Enum-Klasse) gar nicht vorhanden ist,
genauso könnte schlechtes switch später angemeckert werden,

aber der Aufwand und so eine Blöße zuzulassen lohnt sicherlich nicht, die alternative Variante ist sowieso besser, zumal noch leserlicher:

 
case PUDEL :  // ohne Hund.
...
case SCHAEFERHUND: // ohne Hund.

[QUOTE=SlaterB]
aber der Aufwand und so eine Blöße zuzulassen lohnt sicherlich nicht, die alternative Variante ist sowieso besser, zumal noch leserlicher:

 
case PUDEL :  // ohne Hund.
...
case SCHAEFERHUND: // ohne Hund.
```[/QUOTE]

würde ich auch sagen - unter Umständen kann der Code auch gleich in die Enum-Klasse

Hund.values[x].methodeDieDenCodeImSwitchausfuehrt(); // vorher prüfen

Also habe es jetzt mit values gelöst. Der Fehler bestand darin, dass der Code zuvor mit Java8 statt mit meinem Java7 kompilliert war…
ordinal() geht natürlich trotzdem nicht.

Danke an dich Bleiglanz! :slight_smile: