Integer i =...switch(i){casenull:
doSomething0();break;}
W powyższym kodzie nie mogę użyć null w instrukcji case switch. Jak mogę to zrobić inaczej? Nie mogę korzystać default, bo wtedy chcę zrobić coś innego.
Nie można używać dowolnych obiektów w switchinstrukcjach * . Powodem, dla którego kompilator nie narzeka na to, switch (i)gdzie ijest, jest Integerto, że Java automatycznie rozpakowuje Integerplik na int. Jak już powiedzieli assyli, rozpakowanie rzuci NullPointerExceptionkiedy ibędzie null.
* Od wersji Java 7 można używać Stringw switchinstrukcjach.
Ma to sens, że nie można użyć zerowej liczby całkowitej lub innej klasy opakowania z powodu rozpakowania. A co z wyliczeniami i łańcuchami? Dlaczego nie mogą być zerowe?
Nie rozumiem, dlaczego zwarcie wartości zerowej jest mapowane na przypadek „domyślny” lub przypadek specjalny przełącznika zerowego nie został zaimplementowany dla ciągów. Ułatwia to stosowanie przełączników w celu uproszczenia kodu, ponieważ zawsze trzeba wykonać kontrolę zerową. Nie twierdzę jednak, że uproszczenie jest jedynym zastosowaniem przełączników.
@ Reimius nie zawsze musisz wykonać kontrolę zerową. Jeśli przestrzegasz kontraktów kodowych, które podajesz swoim metodom, prawie zawsze możesz nie dopuścić do zaśmiecenia kodu zerowymi kontrolami. Używanie asertów jest zawsze przyjemne.
Chciałbym również poznać odpowiedź na zapytanie @ LuanNico. Wydaje się nieuzasadnione, że nullnie może to być poprawny przypadek podczas pracy z Stringi enumtypami. Być może enumimplementacja polega na wywołaniu ordinal()za kulisami (chociaż mimo to, dlaczego nie traktować jej nulljako „porządkowej” -1?), A Stringwersja robi coś przy użyciu intern()i porównuje wskaźniki (lub w inny sposób opiera się na czymś, co ściśle wymaga dereferencji obiekt)?
switch(i)wyrzuci NullPointerException, jeśli tak null, ponieważ spróbuje rozpakować plik Integerw int. Tak więc case null, co okazuje się nielegalne, i tak nigdy nie zostałoby osiągnięte.
Musisz sprawdzić, czy i nie jest zerowy przed switchinstrukcją.
Zakaz używania wartości null jako etykiety przełącznika uniemożliwia pisanie kodu, którego nigdy nie można wykonać. Jeśli wyrażenie przełączające jest typu referencyjnego, takiego jak pierwotny element w pudełku lub wyliczenie, wystąpi błąd w czasie wykonywania, jeśli wyrażenie będzie miało wartość zerową w czasie wykonywania.
Przed wykonaniem instrukcji Swithch musisz sprawdzić, czy wartość jest pusta.
Dla mnie zwykle jest to zgodne z tabelą przeglądową w bazie danych (tylko dla tabel rzadko aktualizowanych).
Jednak gdy próbuję użyć findByTypeIdw instrukcji switch (najprawdopodobniej z danych wejściowych użytkownika) ...
int userInput =3;PersonType personType =PersonType.findByTypeId(userInput);switch(personType){case COOL_GUY:// Do things only a cool guy would do.break;case JERK:// Push back. Don't enable him.break;default:// I don't know or care what to do with this mess.}
... jak stwierdzili inni, skutkuje to NPE @ switch(personType) {. Jednym obejściem (tj. „Rozwiązaniem”), które zacząłem wdrażać, było dodanie UNKNOWN(-1)typu.
Teraz nie musisz sprawdzać wartości null tam, gdzie się liczy, i możesz wybrać obsługę UNKNOWNtypów. (UWAGA: -1jest mało prawdopodobnym identyfikatorem w scenariuszu biznesowym, ale oczywiście wybierz coś, co ma sens w twoim przypadku użycia).
Niektóre biblioteki próbują oferować alternatywy dla wbudowanej switchinstrukcji Java . Vavr jest jednym z nich, uogólniają go do dopasowywania wzorców.
String s =Match(i).of(Case($(1),"one"),Case($(2),"two"),Case($(),"?"));
Możesz użyć dowolnego predykatu, ale oferuje on wiele z nich po wyjęciu z pudełka i $(null)jest całkowicie legalny. Uważam to za bardziej eleganckie rozwiązanie niż alternatywy, ale wymaga to java8 i zależności od biblioteki vavr ...
Nie możesz Możesz używać prymitywów (int, char, short, byte) i String (Strings in java 7 only) w przełączniku. prymitywy nie mogą mieć wartości zerowej.
Sprawdź iw osobnym stanie przed zmianą.
jeśli wyliczenie jest zerowe, będziesz miał ten sam problem. BTW, to dość dziwne, że przełącznik nie może obsłużyć wartości null, ponieważ ma domyślną klauzulę
1
@LeonardoKenji Domyślna klauzula tak naprawdę nie ma nic wspólnego z wartością null; cokolwiek włączysz, zostanie odesłane w celu sprawdzenia innych przypadków, więc domyślna klauzula nie będzie obsługiwać przypadku zerowego (wyjątek NullPointerEx jest zgłaszany, zanim będzie miał szansę).
Myślę, że miał na myśli, że domyślna klauzula powinna obsługiwać wartość null, jak każda inna możliwa wartość wyliczenia, która nie została uchwycona przez poprzednią sprawę
w przypadku prymitywów wiemy, że może to zawieść z NPE do automatycznego boxowania
ale dla String lub wyliczenia , może być równa wywoływanie metody, która oczywiście musi wartość LHS na co równa jest wywoływany. Tak więc, biorąc pod uwagę, że żadna metoda nie może być wywołana na wartości null, przełącz uchwyt cant null.
Używamy plików cookie i innych technologii śledzenia w celu poprawy komfortu przeglądania naszej witryny, aby wyświetlać spersonalizowane treści i ukierunkowane reklamy, analizować ruch w naszej witrynie, i zrozumieć, skąd pochodzą nasi goście.
Kontynuując, wyrażasz zgodę na korzystanie z plików cookie i innych technologii śledzenia oraz potwierdzasz, że masz co najmniej 16 lat lub zgodę rodzica lub opiekuna.