|
|
Linia 273: |
Linia 273: |
| Czy deklaracja wyjątków należy do sygnatury metody? Przygotuj przykład, który to rozstrzyga. | | Czy deklaracja wyjątków należy do sygnatury metody? Przygotuj przykład, który to rozstrzyga. |
|
| |
|
| {{rozwiazanie|||<div class="mw-collapsible mw-made=collapsible mw-collapsed"><div class="mw-collapsible-content" style="display:none">
| | <div class="mw-collapsible mw-made=collapsible mw-collapsed"> |
| | <span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie</span> |
| | <div class="mw-collapsible-content" style="display:none"> |
| Nie. Deklaracja wyjątków nie należy do sygnatury metody, tak samo jak wartość zwrotna. | | Nie. Deklaracja wyjątków nie należy do sygnatury metody, tak samo jak wartość zwrotna. |
| '''class''' WyjA '''extends''' Exception {} | | '''class''' WyjA '''extends''' Exception {} |
Linia 287: |
Linia 289: |
| } | | } |
| </div> | | </div> |
| </div>}} | | </div> |
Aktualna wersja na dzień 20:23, 28 maj 2020
<<< Powrót do przedmiotu Programowanie obiektowe
<<< Powrót do wykładu Wyjątki
Zadanie 1
Napisz metodę, która 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 jednym bloku catch dla każdego z wyjątków. Niech każdy blok 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 blokach catch mogą być obsłużone przez ten sam blok lub jeden z pozostałych bloków 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 Exception {}
}