Zagadki Java zawierają różnego rodzaju niuanse języka i „podchwytliwe” fragmenty kodu. Każda następna zagadka będzie zawierała odpowiedź i wyjaśnienie do poprzedniej. Lista wszystkich zagadek.
Jeżeli znasz odpowiedź, podziel się nią w komentarzu!
Zagadka Java #6¶
Które z poniższych linii kodu klasy SpotTheError spowodują błąd kompilacji i dlaczego?
public class SpotTheError { public static final void main(String[] args) { long longVal = 9876543210; int intVal1 = 1_0; int intVal2 = 0xff; String $fiveDollars = "$5"; String #ofPuzzlesSoFar = 6; float floatVal1 = 0; float floatVal2 = 0.0; byte byteVal1 = 1; byte byteVal2 = (byte) -129; long anotherLong = 1; switch (anotherLong) { case 0: System.out.println("0"); break; default: System.out.println(anotherLong); break; } } }
Odpowiedź do poprzedniej zagadki #5¶
Poniżej znajdziesz odpowiedź do poprzedniej zagadki.
Próba kompilacja klasy MyExceptionTest zakończy się następującym błędem kompilacji:
Problem występuje w drugiej instrukcji try..catch, w której próbujemy obsłużyć wyjątek rodzaju Checked. O tym, że jest to wyjątek rodzaju Checked świadczy to, że dziedziczy on po klasie Exception, i nie ma w swojej hierarchii dziedziczenia klasy RuntimeException:
class MyException extends Exception {}
Jeżeli wywołanie metody może skutkować rzuceniem wyjątku rodzaju Checked, to, w przeciwieństwie do wyjątków Unchecked, metoda musi zdefiniować taki wyjątek za pomocą klauzuli throws w swojej sygnaturze. Tak dzieje się w przypadku metody m, która definiuje potencjał rzucenia wyjątku MyException:
public static void m() throws MyException {}
Próba wywołania tej metody z wykorzystaniem try..catch jest prawidłowa:
try { m(); } catch (MyException e) {}
Jednakże, w przypadku metody m2, która nie definiuje żadnego wyjątku za pomocą throws:
public static void m2() {}
Nie możemy skorzystać z try..catch:
try { m2(); } catch (MyException e) {}
Kompilator zaprotestuje – próbujemy złapać wyjątek rodzaju Checked, wywołując metodę, która nie deklaruje możliwości rzucenia takiego wyjątku.
Jest to jedyny błąd, jaki zgłosi kompilator. Dlaczego w przypadku metody m3, która także nie deklaruje rzucania wyjątku, kompilator nie zgłasza podobnego błędu?
public static void m3() {} ... try { m3(); } catch (Exception e) {}
W przypadku metody m3 łapany jest wyjątek typu Exception, który jest bazową klasą zarówno dla wyjątków Checked, jak i Unchecked (zwanych także runtime exceptions). Potencjał rzucenia wyjątku rodzaju Unchecked przez metodę m3 nie musi być deklarowany, ale może być obsłużony przez instrukcję try z klauzulą catch definiującą Exception jako łapany wyjątek, ponieważ wszystkie wyjątki rodzaju Unchecked dziedziczą po klasie Exception. Dlatego kod w tym przypadku kompiluje się bez błędów. W przypadku metody m2 kompilator zgłasza błąd, bo łapanie własnego wyjątku, który jest rodzaju Checked, nie daje takiej możliwości.
W moim kursie Nauka programowania w języku Java znajdziesz rozdział dedykowany wyjątkom, z których dowiesz się najważniejszych informacji o ich używaniu: