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: