2012-05-11 3 views
7
enum Color {RED, GREEN, BLUE}; 
class SwitchEnum 
{ 
    public static void main(String[] args) 
    { 
    Color c = Color.GREEN; 
    switch(c) 
    { 
     case RED: 
     System.out.println("red"); 
     break; 
     case GREEN: 
     System.out.println("green"); 
     break; 
     case BLUE: 
     System.out.println("blue"); 
     break; 
    } 
    } 
} 

Powyższy kod jest kompilowany poprawnie i daje oczekiwany wynik.wyliczanie enum w przypadku przełącznika

Moje pytanie brzmi: dlaczego tworząc odniesienie do koloru "c", musieliśmy odnieść je poprzez nazwę enum (tzn. Color.GREEN), ale w bloku case wystarczyła tylko wartość wyliczeniowa. Nie powinien być

case Color.RED: 

itp. ???

Odpowiedz

5

Nie, nie powinien. Kompilator Java jest wystarczająco inteligentny, aby wiedzieć, że włączasz Color, a więc język pozwala na ten skrót (i jak zauważa Paul, wymaga tego). W rzeczywistości cała kompilacja instrukcji switch zależy od tego, czy kompilator wie, co włączasz, ponieważ przekształca przełącznik w tabelę przeskakiwania na podstawie indeksu określonej przez ciebie wartości wyliczeniowej. Dopiero od niedawna można było włączać nieliczbowe rzeczy, takie jak String.

Istotna część specyfikacji języka jest w JLS Chapter 14.11:

... 
SwitchLabel: 
    case ConstantExpression : 
    case EnumConstantName : 
    default : 

EnumConstantName: 
    Identifier 

Jeśli szukasz wgląd dlaczego język został zaprojektowany tak było, że będzie trudno odpowiedz obiektywnie. Projektowanie języka jest zniuansowane i musisz wziąć pod uwagę, że składnia przypisania została napisana wiele lat przed dodaniem obsługi enum.

+1

+1 W rzeczywistości * masz *, aby użyć skrótu. Zobacz [ten interesujący post] (http://stackoverflow.com/q/8481635/697449) na przykład. –

+0

@Paul: Etykieta przypadku enum switch ** MUSI ** być _naqualified_ nazwą stałej wyliczeniowej. thnx ... mam to ... – WickeD

2

Jest to konwencja językowa. Wiele różnych języków ma znaczenie i nie wszyscy to robią. W przypadku Javy możesz zrobić Color.RED lub cokolwiek z powodu przestrzeni nazw. W ten sposób możesz mieć wiele wyliczeń o tych samych nazwach zmiennych i nie kolidują one.

Powód, dla którego instrukcja switch nie wymaga wykonywania Color.RED (i pozwala po prostu podać RED) jest taka, że ​​instrukcja switch wie, że jest wyliczeniem typu Color i szuka w tym obszarze nazw.

1

W linii

Color c = Color.GREEN; 

Color. jest wymagane, ponieważ kompilator Java nie wywnioskować typ przypisanego wyrażenia (Color.GREEN) z deklaracji (Color c). Z tego samego powodu, trzeba napisać:

ArrayList<String> x = new ArrayList<String>(); 

a nie po prostu

ArrayList<String> x = new ArrayList(); 

(to jest rzeczywiście częściowo rozwiązany w Java 7, ale to już inna historia). W rachunku switch(...), typ case jest jednak wnioskowane z typu switch.