2012-05-30 17 views
81

Mam szalone pytanie dotyczące przełączników Java.Deklarowanie i inicjowanie zmiennych w przełącznikach Java

int key = 2; 

switch (key) { 
    case 1: 
     int value = 1; 
     break; 
    case 2: 
     value = 2; 
     System.out.println(value); 
     break; 
    default: 
     break; 
} 

Scenariusz 1 - Kiedy key jest dwa powodzeniem drukować wartość jako 2.
Scenariusz 2 - Kiedy idę do komentowania value = 2 w case 2: to squawks mówiąc Lokalna wartość zmiennej nie może mieć został zainicjowany.

Pytania:

Scenariusz 1: Jeśli przepływ wykonanie nie iść do case 1: (gdy key = 2), a następnie, jak to poznać typ zmiennej wartości jako int?
Scenariusz 2: Jeśli kompilator zna typ zmiennej wartości jako int, musi mieć dostęp do wyrażenia int value = 1; w . (Deklaracja i inicjalizacja). Więc dlaczego to sqawrk Kiedy mam zamiar skomentować value = 2 w case 2:, mówiąc: Wartość zmiennej lokalnej może nie zostać zainicjowana.

+9

To nie jest szalone pytanie, to bardzo dobre pytanie. – biziclop

+0

Możliwy duplikat zakresu [Zakres zmiennej w przypadku przełącznika] (http://stackoverflow.com/questions/3894119/variables-scope-in-a-switch-case) –

+0

@PhilippeCarriere Właściwie, myślę, że powinien być odwrotnie - odpowiedź tutaj jest lepsza (nawet jeśli post jest nowszy), ponieważ istnieje bezpośrednie odniesienie do JLS i dobrze podsumowuje problem, który obejmuje różne odpowiedzi w tym poście. [Zobacz także] (http://meta.stackoverflow.com/questions/251938/should-i-flag-a-question-as-duplicate-if-it-has-received-better-answers). – Tunaki

Odpowiedz

96

Instrukcje przełączania są zasadniczo nieparzyste pod względem zakresu. Od section 6.3 of the JLS:

Zakres deklaracji zmiennej lokalnej w bloku (§14.4) to reszta bloku, w którym pojawia się deklaracja, wychodząc z własnym inicjatora i tym żadnych dalszych declarators w prawo w instrukcja deklaracji zmiennej lokalnej.

W twoim przypadku, case 2 jest w tym samym blokujak case 1 i pojawia się po niej, choć case 1 nie wykona ... więc zmienna lokalna jest w zakresie i dostępne dla pisanie pomimo ciebie logicznie nigdy "realizacja" deklaracji. (Deklaracja nie jest naprawdę "wykonywalna", chociaż inicjalizacja jest.)

Jeśli skomentujesz przypisanie value = 2;, kompilator nadal będzie wiedział, do której zmiennej się odwołujesz, ale nie przeszedłeś żadnej ścieżki wykonania, która przypisałaby jej wartość, i dlatego pojawia się błąd jako chciałbyś, gdy spróbujesz odczytać dowolną inną nieokreśloną na pewno zmienną lokalną.

Zdecydowanie polecam nie używać zmiennych lokalnych zadeklarowanych w innych przypadkach - prowadzi to do bardzo mylącego kodu, jak widzieliście. Kiedy wprowadzić zmienne lokalne w sprawozdaniach przełącznik (który ja staram się robić rzadko - przypadki powinny być bardzo krótki, idealnie) I zazwyczaj wolą wprowadzić nowy zakres:

case 1: { 
    int value = 1; 
    ... 
    break; 
} 
case 2: { 
    int value = 2; 
    ... 
    break; 
} 

Wierzę, że to jest bardziej czytelna.

+8

+1 dla "Deklaracja nie jest naprawdę" wykonywalna ", chociaż inicjalizacja jest.". I dziękuję za rady także Skeet. – namalfernandolk

18

Od http://www.coderanch.com/t/447381/java-programmer-SCJP/certification/variable-initialization-within-case-block

Deklaracje są przetwarzane w czasie kompilacji i nie zależą od przepływu wykonanie kodu. Ponieważ value jest zadeklarowany w lokalnym zasięgu zakresu , można go użyć w dowolnym miejscu w tym bloku od punktu jego deklaracji.

+0

dlaczego ta odpowiedź została odrzucona? nie odpowiada na pytanie, w przeciwieństwie do odpowiedzi Paula lub Skeeta ... –

+6

To robi. Więc, +1, grosz, również z mojej strony. –

18

Zmienna została zadeklarowana (jako int), ale nie zainicjowana (przypisana wartość początkowa). Pomyśl o linii:

int value = 1; 

jako:

int value; 
value = 1; 

int value część informuje kompilator w czasie kompilacji, że masz zmienną wartość, która jest int. Część value = 1 inicjuje ją, ale dzieje się to w czasie wykonywania i nie dzieje się wcale, jeśli ta gałąź przełącznika nie zostanie wprowadzona.

+0

+1 dla miłego wyjaśnienia deklaracji i inicjalizacji w czasie kompilacji i czasu wykonywania. – namalfernandolk

Powiązane problemy