|
|
Linia 225: |
Linia 225: |
| | | |
| '''class''' Zasób3 { | | '''class''' Zasób3 { |
| Zasób(int i) { | | Zasób3(int i) { |
| //... | | //... |
| } | | } |
Linia 237: |
Linia 237: |
| '''public''' '''static''' '''void''' main(String[] args) '''throws''' Exception { | | '''public''' '''static''' '''void''' main(String[] args) '''throws''' Exception { |
| '''for''' (int i = 0; i < 10; i++) { | | '''for''' (int i = 0; i < 10; i++) { |
| Zasób3 z = '''new''' Zasób3(); | | Zasób3 z = '''new''' Zasób3(i); |
| '''try''' { | | '''try''' { |
| z.zarezerwuj(); | | z.zarezerwuj(); |
Wersja z 13:18, 28 lip 2006
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
Zmodyfikuj klasę ZwalnianieZasobów2, aby zwalnianie odbywało się w klauzuli finally. Sprawdź, czy rzeczywiście zasób jest zwalniany nawet jak blok try jest opuszczany przy pomocy instrukcji return,
break i continue.
Rozwiązanie
import java.io.IOException;
class InnyMożliwyWyjątek extends Exception {}
class Zasób3 {
Zasób3(int i) {
//...
}
void zarezerwuj() {}
void używaj() throws IOException {}
void innaNiebezpiecznaOperacja() throws InnyMożliwyWyjątek {}
void zwolnij() {}
}
public class ZwalnianieZasobów3 {
public static void main(String[] args) throws Exception {
for (int i = 0; i < 10; i++) {
Zasób3 z = new Zasób3(i);
try {
z.zarezerwuj();
//tu jest niebezpieczny kod
z.używaj();
z.innaNiebezpiecznaOperacja();
//trzeba zwolnić zasób, bo kończy się obrót pętli
if (i == 3) continue;
//trzeba zwolnić zasób, bo kończy się cała metoda
if (i == 8) return;
//...
//zwalnianie zasobów
z.zwolnij();
} catch (IOException e) {
//obsługa wyjątku IOException
} catch (InnyMożliwyWyjątek w) {
//obsługa wyjątku InnyMożliwyWyjątek
} finally {
//zwalnianie zasobów
z.zwolnij();
}
}
}
}