<<< Powrót
<<< Powrót do modułu 7
Zadanie 1
Napisz metodę, które jako parametr będzie przyjmowała napis i wypisywała na standardowe wyjście jego długość.
- Przekaż do tej metody null i zobacz jaki wyjątek został zgłoszony.
- Otocz wywołanie metody blokiem try-catch, przechwyć ten wyjątek i wypisz na standardowe wyjście ślad stosu wywołań z chwili zgłoszenia wyjątku.
- Bezpośrednio po wypisaniu jego śladu zgłoś obsługiwany wyjątek ponownie.
- Czy ślady stosu wypisane przez ciebie w bloku catch i przez maszynę wirtualną w chwili przerwania programu są takie same?
- Przed zgłoszeniem ponownie obsługiwanego wyjątku wykonaj na nim metodę fillInStackTrace().
- Zamiast zgłaszać ponownie obsługiwany wyjątek zgłoś nowy wyjątek klasy Exception. Zauważ, że wymaga to pewnej dodatkowej zmiany w kodzie.
- Dołącz obsługiwany wyjątek do nowo tworzonego wyjątku Exception jako przyczynę jego powstania.
Rozwiązanie (część 1)
public class Zad1 {
void wypiszDługość(String s) {
System.out.println(s.length());
}
public static void main(String[] args) {
Zad1 z = new Zad1();
z.wypiszDługość(null);
}
}
Rozwiązanie (część 2)
public class Zad1 {
void wypiszDługość(String s) {
System.out.println(s.length());
}
public static void main(String[] args) {
try {
Zad1 z = new Zad1();
z.wypiszDługość(null);
} catch (NullPointerException w) {
w.printStackTrace(System.out);
}
}
}
Rozwiązanie (część 3)
public class Zad1 {
void wypiszDługość(String s) {
System.out.println(s.length());
}
public static void main(String[] args) {
try {
Zad1 z = new Zad1();
z.wypiszDługość(null);
} catch (NullPointerException w) {
w.printStackTrace(System.out);
throw w;
}
}
}
Rozwiązanie (część 5)
public class Zad1 {
void wypiszDługość(String s) {
System.out.println(s.length());
}
public static void main(String[] args) {
try {
Zad1 z = new Zad1();
z.wypiszDługość(null);
} catch (NullPointerException w) {
w.printStackTrace(System.out);
w.fillInStackTrace();
throw w;
}
}
}
Rozwiązanie (część 6)
public class Zad1 {
void wypiszDługość(String s) {
System.out.println(s.length());
}
public static void main(String[] args) throws Exception {
try {
Zad1 z = new Zad1();
z.wypiszDługość(null);
} catch (NullPointerException w) {
w.printStackTrace(System.out);
throw new Exception();
}
}
}
Rozwiązanie (część 7)
public class Zad1 {
void wypiszDługość(String s) {
System.out.println(s.length());
}
public static void main(String[] args) throws Exception {
try {
Zad1 z = new Zad1();
z.wypiszDługość(null);
} catch (NullPointerException w) {
throw new Exception(w);
}
}
}
Zadanie 2
Napisz trzy nowe wyjątki oraz metodę, która za każdym wywołanie będzie losowo zgłaszała jeden z nich.
- Otocz wywołanie tej metody instrukcją try-catch zawierającą po klauzuli catch dla każdego z wyjątków. Niech każda klauzula catch wypisuje który wyjątek złapała.
- Sprawdź co się stanie jeżeli zmienisz kod metody tak żeby przestała zgłaszać jeden z wyjątków, ale nadal będzie on wymieniony w klauzuli throws nagłówka metody. Czy metody wywołujące napisaną przez ciebie metodę, ale nie obsługujące tego wyjątku będą musiały nadal go wymieniać w swoich nagłówkach?
Rozwiązanie (część 1)
class MójWyjątekA extends Exception {}
class MójWyjątekB extends Exception {}
class MójWyjątekC extends Exception {}
public class Zad2 {
void losujWyjątek() throws MójWyjątekA, MójWyjątekB, MójWyjątekC {
java.util.Random r = new java.util.Random();
switch (r.nextInt(3)) {
case 0: throw new MójWyjątekA();
case 1: throw new MójWyjątekB();
case 2: throw new MójWyjątekC();
}
}
public static void main(String[] args) {
Zad2 z = new Zad2();
try {
z.losujWyjątek();
} catch (MójWyjątekA w) {
System.out.println(w.getClass());
} catch (MójWyjątekB w) {
System.out.println(w.getClass());
} catch (MójWyjątekC w) {
System.out.println(w.getClass());
}
}
}
Rozwiązanie (część 2)
Tak, będą musiały. W ten sposób możemy wymusić, by kod korzystający z tej metody był przygotowany na wyjątek, który może się pojawić w jej kolejnej wersji.
Zadanie 3
Napisz program sprawdzający, czy wyjątki zgłoszone w klauzuli catch mogą być obsłużone przez tą samą klauzulę lub jedną z pozostałych klauzul tej samej instrukcji try-catch.
Rozwiązanie
class MójWyjątek extends Exception {
public MójWyjątek() {
super();
}
public MójWyjątek(String s) {
super(s);
}
}
public class Zad3 {
public static void main(String[] args) throws Exception {
try {
throw new MójWyjątek("oryginalny");
} catch (MójWyjątek w) {
java.util.Random r = new java.util.Random();
switch (r.nextInt(3)) {
case 0: throw w;
case 1: throw new MójWyjątek("nowy");
case 2: throw new Exception();
}
} catch (Exception w) {}
}
}
Zadanie 4
W poniższym przykładzie w bloku try jest pięć instrukcji. Każda z nich może zgłosić taki sam wyjątek. Zaproponuj rozwiązanie, które w kodzie obsługi wyjątku pozwoli sprawdzić w której instrukcji on wystąpił.
public class Zad4 {
void możeZgłosićWyjątek() throws Exception {
if (new java.util.Random().nextInt(5) == 0)
throw new Exception();
}
public static void main(String[] args) {
Zad4 z = new Zad4();
try {
z.możeZgłosićWyjątek();
z.możeZgłosićWyjątek();
z.możeZgłosićWyjątek();
z.możeZgłosićWyjątek();
z.możeZgłosićWyjątek();
} catch (Exception e) {
//jakiś kod obsługi
}
}
}
Rozwiązanie
public class Zad4 {
void możeZgłosićWyjątek() throws Exception {
if (new java.util.Random().nextInt(5) == 0)
throw new Exception();
}
public static void main(String[] args) {
Zad4 z = new Zad4();
int i = 1;
try {
z.możeZgłosićWyjątek();
i++;
z.możeZgłosićWyjątek();
i++;
z.możeZgłosićWyjątek();
i++;
z.możeZgłosićWyjątek();
i++;
z.możeZgłosićWyjątek();
i++;
} catch (Exception e) {
System.out.println("Wyjątek wystąpił w instrukcji "+ i);
//jakiś kod obsługi
}
if (i == 6) System.out.println("Wyjątek nie wystąpił");
}
}
Zadanie 5
Czy deklaracja wyjątków należy do sygnatury metody? Przygotuj przykład, który to rozstrzyga.
Rozwiązanie
Nie. Deklaracja wyjątków nie należy do sygnatury metody, tak samo jak wartość zwrotna.
class WyjA extends Exception {}
class WyjB extends Exception {}
public class Zad5 {
//z poniższych metod może być odkomentowana tylko jedna!
//void test() {}
//void test() throws WyjA {}
//void test() throws WyjB {}
//void test() throws WyjA, WyjB {}
//void test() throws Exceptions {}
}