Mam szalone pytanie dotyczące przełączników 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 - gdy key
jest dwa, pomyślnie drukuje wartość jako 2.
Scenariusz 2 - Kiedy mam zamiar skomentować value = 2
w case 2:
nim, wrzeszczy, mówiąc, że wartość zmiennej lokalnej mogła nie zostać zainicjowana .
Pytania:
Scenariusz 1: Jeśli przepływ wykonania nie przejdzie do case 1:
(kiedy key = 2
), to skąd będzie wiedzieć, jaki typ zmiennej wartości int
?
Scenariusz 2: Jeśli kompilator zna typ zmiennej wartości jako int
, to musi mieć dostęp do int value = 1;
wyrażenia w case 1:
. (Deklaracja i inicjalizacja). Więc dlaczego to robi sqawrk Kiedy mam zamiar wypowiedzieć value = 2
się case 2:
, mówiąc lokalną wartość zmiennej nie została zainicjowana .
java
scope
initialization
switch-statement
declaration
namalfernandolk
źródło
źródło
Odpowiedzi:
Instrukcje przełączania są zasadniczo dziwne pod względem zakresu. Z sekcji 6.3 JLS :
W twoim przypadku,
case 2
to w tym samym bloku , jakcase 1
i pojawia się po to, mimo żecase 1
nigdy nie będzie wykonać ... więc zmienna lokalna jest dostępny w zakresie i na pisanie mimo was logicznie nigdy „wykonanie” oświadczenie. (Deklaracja nie jest tak naprawdę „wykonywalna”, chociaż inicjalizacja jest.)Jeśli zakomentujesz
value = 2;
przypisanie, kompilator nadal wie, do której zmiennej się odnosisz, ale nie przejdziesz przez żadną ścieżkę wykonania, która przypisuje mu wartość, dlatego otrzymujesz błąd, tak jak przy próbie przeczytaj dowolną inną zmienną lokalną nie przypisaną na pewno.Zdecydowanie zalecamy nie używać zmiennych lokalnych zadeklarowanych w innych przypadkach - prowadzi to do bardzo mylące kod, jak widzieliście. Kiedy wprowadzam zmienne lokalne w instrukcjach switch (co staram się robić rzadko - przypadki powinny być bardzo krótkie, najlepiej), zazwyczaj wolę wprowadzić nowy zakres:
Uważam, że to jest jaśniejsze.
źródło
Zmienna została zadeklarowana (jako liczba całkowita), ale nie została zainicjowana (przypisano jej wartość początkową). Pomyśl o linii:
Tak jak:
int value
Część informuje kompilator w czasie kompilacji, że masz zmienną wartość, która jest int.value = 1
Część inicjuje go, ale zdarza się, że w czasie wykonywania, a nie stanie, jeśli w ogóle, że oddział przełącznika nie jest wpisany.źródło
Z http://www.coderanch.com/t/447381/java-programmer-SCJP/certification/variable-initialization-within-case-block
źródło
Dzięki integracji JEP 325: Switch Expressions (Preview) w wersjach wczesnego dostępu JDK-12. Istnieją pewne zmiany, które można zobaczyć w odpowiedzi Jona -
Zakres zmiennej lokalnej - zmienne lokalne w przypadkach przełączników mogą być teraz lokalne dla samej sprawy zamiast całego bloku przełącznika . Przykład (podobny do tego, co Jon również próbował syntaktycznie) rozważający
Day
klasę wyliczenia w celu dalszego wyjaśnienia:Przełącz wyrażenia - jeśli celem jest przypisanie wartości do zmiennej, a następnie wykorzystanie jej, raz można użyć wyrażeń przełączających. na przykład
źródło
To wyjaśnienie może pomóc.
źródło
Specyfikacja Java:
https://docs.oracle.com/javase/specs/jls/se12/html/jls-14.html#jls-14.11
https://docs.oracle.com/javase/specs/jls/se12/html/jls-14.html#jls-14.7
Oznakowane oświadczenia:
Innymi słowy, przypadek 1, przypadek 2 to etykiety w instrukcji switch. Instrukcje break i continue można zastosować do etykiet.
Ponieważ etykiety współużytkują zakres instrukcji, wszystkie zmienne zdefiniowane w etykietach współużytkują zakres instrukcji switch.
źródło