PO Wyjątki - ćwiczenia: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Jsroka (dyskusja | edycje)
 
(Nie pokazano 26 wersji utworzonych przez 4 użytkowników)
Linia 1: Linia 1:
{{powrot|Programowanie obiektowe|do przedmiotu Programowanie obiektowe}}
{{powrot|PO Wyjątki|do wykładu Wyjątki}}
== Zadanie 1 ==
== Zadanie 1 ==
Napisz metodę, które jako parametr będzie przyjmowała napis i wypisywała na standardowe wyjście jego długość.
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.
# 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.
# 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.
# 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?
# 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()''.
# 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.
# 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.
# Dołącz obsługiwany wyjątek do nowo tworzonego wyjątku ''Exception'' jako przyczynę jego powstania.


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie (część 1)''' 
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie (Część 1)</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
  '''public''' '''class''' Zad1 {
  '''public''' '''class''' Zad1 {
Linia 24: Linia 28:
</div>
</div>
</div>
</div>
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie (część 2)''' 
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie (Część 2)</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
  '''public''' '''class''' Zad1 {
  '''public''' '''class''' Zad1 {
Linia 46: Linia 49:


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie (część 3)''' 
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie (Część 3)</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
  '''public''' '''class''' Zad1 {
  '''public''' '''class''' Zad1 {
Linia 67: Linia 70:


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie (część 4)''' 
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie (Część 4)</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
Tak
Tak
Linia 74: Linia 77:


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie (część 5)''' 
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie (Część 5)</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
  '''public''' '''class''' Zad1 {
  '''public''' '''class''' Zad1 {
Linia 96: Linia 99:


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie (część 6)''' 
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie (Część 6)</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
  '''public''' '''class''' Zad1 {
  '''public''' '''class''' Zad1 {
Linia 115: Linia 118:
</div>
</div>
</div>
</div>
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie (część 7)''' 
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie (Część 7)</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
  '''public''' '''class''' Zad1 {
  '''public''' '''class''' Zad1 {
Linia 138: Linia 140:
== Zadanie 2 ==
== 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.
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.
# 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?
# 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?


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie (część 1)''' 
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie (Część 1)</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
  '''class''' MójWyjątekA '''extends''' Exception {}
  '''class''' MójWyjątekA '''extends''' Exception {}
Linia 175: Linia 177:


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie (część 2)''' 
<span class="mw-collapsible-toogle mw-collapsible-toogle-default style="font-variant:small-caps">Rozwiązanie (Część 2)</span>
<div class="mw-collapsible-content" style="display:none">
<div class="mw-collapsible-content" style="display:none">
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.  
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.  
Linia 182: Linia 184:


== Zadanie 3 ==
== 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'''.
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'''.


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie''' 
<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">
<div class="mw-collapsible-content" style="display:none">
  '''class''' MójWyjątek '''extends''' Exception {
  '''class''' MójWyjątek '''extends''' Exception {
Linia 215: Linia 217:


== Zadanie 4 ==
== 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''',
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ł.
'''break''' i '''continue'''.
'''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
    }
  }
}
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie''' 
<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">
<div class="mw-collapsible-content" style="display:none">
  '''import''' java.io.IOException;
  '''public''' '''class''' Zad4 {
  '''void''' możeZgłosićWyjątek() '''throws''' Exception {
'''class''' InnyMożliwyWyjątek '''extends''' Exception {}
    '''if''' ('''new''' java.util.Random().nextInt(5) == 0)
      '''throw''' '''new''' Exception();
'''class''' Zasób3 {
  Zasób3(int i) {
    //...
   }
   }
  '''void''' zarezerwuj() {}
 
  '''void''' używaj() '''throws''' IOException {}
   '''public''' '''static''' '''void''' main(String[] args) {
  '''void''' innaNiebezpiecznaOperacja() '''throws''' InnyMożliwyWyjątek {}
     Zad4 z = '''new''' Zad4();
  '''void''' zwolnij() {}
    '''int''' i = 1;
}
    '''try''' {
      z.możeZgłosićWyjątek();
'''public''' '''class''' ZwalnianieZasobów3 {
      i++;
   '''public''' '''static''' '''void''' main(String[] args) '''throws''' Exception {
      z.możeZgłosićWyjątek();
     '''for''' (int i = 0; i < 10; i++) {
      i++;
      Zasób3 z = '''new''' Zasób3(i);
      z.możeZgłosićWyjątek();
      '''try''' {
      i++;
        z.zarezerwuj();
      z.możeZgłosićWyjątek();
      i++;
        //tu jest niebezpieczny kod
      z.możeZgłosićWyjątek();
        z.używaj();
       i++;
        z.innaNiebezpiecznaOperacja();
    } '''catch''' (Exception e) {
        '''if''' (i == 3) '''continue''';
       System.out.println("Wyjątek wystąpił w instrukcji "+ i);
        '''if''' (i == 8) '''return''';
       //jakiś kod obsługi
        //...
        //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();
      }
     }
     }
    '''if''' (i == 6) System.out.println("Wyjątek nie wystąpił");
   }
   }
  }
  }
Linia 265: Linia 271:


== Zadanie 5 ==
== Zadanie 5 ==
Podczas rezerwowania i zwalniania zasobów zazwyczaj też może wystąpić wyjątek. Użyj pokazanej poniższej klasy ''Zasób3'' i zmodyfikuj swoje rozwiązanie poprzedniego zadania, tak aby zawsze oba zasoby były zwalniane. Zadbaj żeby nie dochodziło do zaginięcia żadnych wyjątków. Możesz założyć, że wykonanie operacji ''zwolnij()'' na zamkniętym zasobie jest dozwolone.
Czy deklaracja wyjątków należy do sygnatury metody? Przygotuj przykład, który to rozstrzyga.
'''class''' InnyMożliwyWyjątek '''extends''' Exception {}
'''class''' JeszczeInnyMożliwyWyjątek '''extends''' Exception {}
'''class''' Zasób3 {
  Zasób3(int i) {
    //...
  }
  '''void''' zarezerwuj() '''throws''' IOException {}
  '''void''' używaj() '''throws''' IOException {}
  '''void''' innaNiebezpiecznaOperacja() '''throws''' InnyMożliwyWyjątek, JeszczeInnyMożliwyWyjątek {}
  '''void''' zwolnij() '''throws''' IOException {}
}


<div class="mw-collapsible mw-made=collapsible mw-collapsed">
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie''' 
<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">
<div class="mw-collapsible-content" style="display:none">
  '''public''' '''class''' ZwalnianieZasobów3 {
Nie. Deklaracja wyjątków nie należy do sygnatury metody, tak samo jak wartość zwrotna.
  '''public''' '''static''' '''void''' main(String[] args) '''throws''' Exception {
  '''class''' WyjA '''extends''' Exception {}
    '''for''' (int i = 0; i < 10; i++) {
'''class''' WyjB '''extends''' Exception {}
      Zasób3 z1 = '''new''' Zasób3(i);
      Zasób3 z2 = '''new''' Zasób3(i);
      '''try''' {
        z1.zarezerwuj();
        z2.zarezerwuj();
   
   
        //tu jest niebezpieczny kod
'''public''' '''class''' Zad5 {
        z1.używaj();
  //z poniższych metod może być odkomentowana tylko jedna!
        z2.używaj();
  //void test() {}
        z1.innaNiebezpiecznaOperacja();
  //void test() throws WyjA {}
        z2.innaNiebezpiecznaOperacja();
  //void test() throws WyjB {}
        '''if''' (i == 3) '''continue''';
  //void test() throws WyjA, WyjB {}
        '''if''' (i == 8) '''return''';
   //void test() throws Exception {}
        //...
        //zwalnianie zasobów
        z1.zwolnij();
        z2.zwolnij();
      } '''catch''' (IOException e) {
        //obsługa wyjątku IOException
      } '''catch''' (InnyMożliwyWyjątek w) {
        //obsługa wyjątku InnyMożliwyWyjątek
      } '''finally''' {
        //obsługa wyjątków jest konieczna,
        //żeby nie dopuścić do zaginięcia JeszczeInnyMożliwyWyjątek
        '''try''' {
          z1.zwolnij();
        } '''catch''' (IOException e) {}
        '''try''' {
          z2.zwolnij();
        } '''catch''' (IOException e) {}
      }
    }
   }
}
</div>
</div>
 
== Zadanie 6 ==
Sprawdź, czy '''finally''' jest wykonywane pomimo wystąpienia wyjątku w bloku '''catch''' z tej samej instrukcji.
<div class="mw-collapsible mw-made=collapsible mw-collapsed">
'''Rozwiązanie''' 
<div class="mw-collapsible-content" style="display:none">
'''public''' '''class''' Zad6 {
  '''public''' '''static''' '''void''' main(String[] args) '''throws''' Exception {
    '''try''' {
      '''throw''' '''new''' Exception();
    } '''catch''' (Exception e) {
      System.out.println("catch");
      '''throw''' '''new''' Exception();
    } '''finally''' {
      System.out.println("finally");
    }
  }
  }
  }
</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ść.

  1. Przekaż do tej metody null i zobacz, jaki wyjątek został zgłoszony.
  2. 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.
  3. Bezpośrednio po wypisaniu jego śladu zgłoś obsługiwany wyjątek ponownie.
  4. Czy ślady stosu wypisane przez ciebie w bloku catch i przez maszynę wirtualną w chwili przerwania programu są takie same?
  5. Przed zgłoszeniem ponownie obsługiwanego wyjątku wykonaj na nim metodę fillInStackTrace().
  6. Zamiast zgłaszać ponownie obsługiwany wyjątek, zgłoś nowy wyjątek klasy Exception. Zauważ, że wymaga to pewnej dodatkowej zmiany w kodzie.
  7. Dołącz obsługiwany wyjątek do nowo tworzonego wyjątku Exception jako przyczynę jego powstania.

Rozwiązanie (Część 1)

Rozwiązanie (Część 2)

Rozwiązanie (Część 3)

Rozwiązanie (Część 4)

Rozwiązanie (Część 5)

Rozwiązanie (Część 6)

Rozwiązanie (Część 7)

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.

  1. 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.
  2. 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)

Rozwiązanie (Część 2)

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

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

Zadanie 5

Czy deklaracja wyjątków należy do sygnatury metody? Przygotuj przykład, który to rozstrzyga.

Rozwiązanie