Java: utilizzo dell'istruzione switch con enum nella sottoclasse


265

Per prima cosa affermerò che ho molta più familiarità con le enumerazioni in C # e sembra che le enumerazioni in Java siano un bel casino.

Come puoi vedere, sto cercando di usare un'istruzione switch @ enums nel mio prossimo esempio, ma ricevo sempre un errore, qualunque cosa stia facendo.

L'errore che ricevo è:

L'etichetta del caso qualificato SomeClass.AnotherClass.MyEnum.VALUE_Adeve essere sostituita con la costante enum non qualificataVALUE_A

Il fatto è che capisco perfettamente l'errore ma non posso semplicemente scrivere VALUE_A poiché l'enum si trova in un'altra sottoclasse. c'è un modo per risolvere questo problema? E perché sta succedendo in Java?

//Main Class
public class SomeClass {

    //Sub-Class
    public static class AnotherClass {
        public enum MyEnum {
            VALUE_A, VALUE_B
        }    
        public MyEnum myEnum;
    }

    public void someMethod() { 
        MyEnum enumExample //...

        switch (enumExample) {
            case AnotherClass.MyEnum.VALUE_A: { <-- error on this line
                //..
                break;
            }
        }
    }
}

Come ha commentato Darrengorman, Java Enumè estremamente utile una volta capito, non è affatto un disastro. Sono molto più flessibili e pratici dei semplici enum (semplicemente un valore intero etichettato) visto su altre piattaforme. Vedi il tutorial Oracle . Scopri le ottimizzazioni Set/ Mapimplementazioni: EnumSet& EnumMap.
Basil Bourque,

1
Quando si tenta di qualificare l'istruzione case; in un certo senso, stai cercando di dire che posso mescolare diversi tipi di enum (non solo lo stesso tipo di enum) all'interno di una singola istruzione switch. Java lo ha fermato con questo approccio, come discusso qui digizol.com/2010/10/enum-case-label-switch-java-qualified.html
lkamal

Questo è successo a me durante il refactoring (spostamento) di una classe in IntelliJ 2018.2
Daniel Alder,

Risposte:


570

Modificalo in questo:

switch (enumExample) {
    case VALUE_A: {
        //..
        break;
    }
}

L'indizio è nell'errore. Non è necessario qualificare le caseetichette con il tipo enum, ma solo il suo valore.


20
Ok, mi sento così stupido :-( Hai perfettamente ragione, ero convinto di aver provato questa linea esatta e ho avuto un errore con quello, quindi sono passato al caso di qualifica, ma il tuo suggerimento FUNZIONA.
Popokoko

4
A proposito, penso che scoprirai che gli enum in Java sono incredibilmente utili una volta che inizi a usarli di più, non direi che sono un casino affatto :)
Darrengorman,

11
@milkplusvellocet, so che questo post è già vecchio, ma sono curioso di sapere perché Java non consente l' etichetta del caso qualificata nell'istruzione switch?
jzarsuelo,

3
@ cRane01 non lo so per certo, ma rende una sintassi più pulita. Specificare il tipo su ciascun caso sarebbe totalmente ridondante
darrengorman,

3
@HelloGoodbye No. La variabile dell'istruzione switch definisce il tipo di istruzione case in modo che possa essere solo una enum.
velocista il

33

Java inserisce automaticamente il tipo di elementi in case, quindi le etichette devono essere non qualificate.

int i;
switch(i) {
   case 5: // <- integer is expected
}
MyEnum e;
switch (e) {
   case VALUE_A: // <- an element of the enumeration is expected
}

14
Perché deve essere non qualificato?
Thorbjørn Ravn Andersen,

11
Se potessi qualificarti, allora potresti usare qualcos'altro di MyEnumcui non avrebbe senso.
Kru,

1
@Kru, ma posso usare qualcosa di grammaticalmente altro per espressioni maiuscole non tipizzate. Ad esempio static final int MY_CONST = 7; …; switch(intVariable) {case MY_CONST: …;}invece di case 7. Quindi questa restrizione per gli enum non ha senso (posso usare non solo i letterali primari, ma anche le costanti definite manualmente per l' switchespressione intera , ma non posso usare le costanti definite manualmente, ma solo i nomi primari per gli enum).
Sasha,

4

questo dovrebbe fare:

//Main Class
public class SomeClass {

    //Sub-Class
    public static class AnotherClass {
        public enum MyEnum {
            VALUE_A, VALUE_B
        }    
        public MyEnum myEnum;
    }

    public void someMethod() { 
        AnotherClass.MyEnum enumExample = AnotherClass.MyEnum.VALUE_A; //...

        switch (enumExample) {
            case VALUE_A: { //<-- error on this line
            //..
            break;
            }
        }
    }
}

Hai salvato la giornata!
Soham Mehta,

3

Sbagliato:

case AnotherClass.MyEnum.VALUE_A

Destra:

case VALUE_A:

1
Ho votato il tuo perché è più chiaro su quale sia il problema.
joaorodr84,

2

Ecco come lo sto usando. E funziona in modo fantastico -

public enum Button {
        REPORT_ISSUES(0),
        CANCEL_ORDER(1),
        RETURN_ORDER(2);

        private int value;

        Button(int value) {
            this.value = value;
        }

        public int getValue() {
            return value;
        }
    }

E switch-casecome mostrato di seguito

@Override
public void onClick(MyOrderDetailDelgate.Button button, int position) {
    switch (button) {
        case REPORT_ISSUES: {
            break;
        }
        case CANCEL_ORDER: {
            break;
        }
        case RETURN_ORDER: {
            break;
        }
    }
}

0

Scrivi someMethod()in questo modo:

public void someMethod() {

    SomeClass.AnotherClass.MyEnum enumExample = SomeClass.AnotherClass.MyEnum.VALUE_A;

    switch (enumExample) {
    case VALUE_A:
        break;
    }

}

Nell'istruzione switch è necessario utilizzare solo il nome costante.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.