1 / 45

Wyjątki, rzutowanie, operator instanceof

Wyjątki, rzutowanie, operator instanceof. Kamil Piekarz Inforamtyka II rok, grupa V prowadzący zajęcia mgr. inż. Dominik Radziszowski. Wyjątki. W czasie wykonania programu mogą wystąpić różne rodzaje błędów:.

qamra
Download Presentation

Wyjątki, rzutowanie, operator instanceof

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Wyjątki, rzutowanie, operator instanceof Kamil PiekarzInforamtyka II rok, grupa Vprowadzący zajęciamgr. inż. Dominik Radziszowski

  2. Wyjątki

  3. W czasie wykonania programu mogą wystąpić różne rodzaje błędów: • po wywołaniu metody obiektu może się okazać, że że obiekt ten ma problemy ze swoim stanem wewnętrznym (niezgodności wartości zmiennych instancyjnych) • obiekt może wykryć błąd w danych na których operuje (błąd operacji plikowej , błąd sieci komputerowej) • obiekt może wykryć naruszenie podstawowych zasad kontraktu • Wielu programistów unika pisania kodu, który sprawdzałby wszystkie możliwe warunki poprawności, ponieważ: • kod, który przy wywołaniu każdej metody sprawdza wiele różnych warunków staje się nieczytelny (konflikt między poprawnością a czytelnością) • po prostu nie zdają sobie sprawy z wszystkich niepoprawnych sytuacji Wyjątki stanowią elegancką metodę sprawdzania poprawności wykonywanych opreacji bez zmniejszania czytelności kodu.

  4. Zróbmy sobie hamburgera...

  5. Diagram klas relacja: składa się z (agregacja)

  6. public class BarSzybkiejObsulugi { public static void main(String[] args) { Hamburger jedzonko = Hamburger.dajHamburgera(); Hamburger drugi = Hamburger.dajHamburgera(); } } publicclass Hamburger { private Mieso mieso; private Bulka bulka; private Salatka salatka; publicstatic Hamburger dajHamburgera() { Hamburger tmp = new Hamburger(); tmp.mieso = Mieso.dajMieso(); tmp.bulka = Bulka.dajBulke(); tmp.salatka = Salatka.dajSalatke(); if ((tmp.mieso != null) && (tmp.bulka != null) && (tmp.salatka != null)) { return tmp; } else { returnnull; } } }

  7. publicclass Mieso { privatestaticint ileNaStanie = 3; publicstatic Mieso dajMieso() { if (ileNaStanie > 0) { ileNaStanie--; returnnew Mieso(); } else { System.out.println("nie ma miesa"); returnnull; } } } publicclass Bulka { privatestaticint ileNaStanie = 1; public static Bulka dajBulke() { if (ileNaStanie > 0) { ileNaStanie--; return new Bulka(); } else { System.out.println("nie ma bulki"); return null; } } }

  8. public class Salatka { private Pomidory pomidory; private Ogorki ogorki; public static Salatka dajSalatke() { Salatka tmp = new Salatka(); tmp.pomidory = Pomidory.dajPomidory(); tmp.ogorki = Ogorki.dajOgorki(); if ((tmp.pomidory != null) && (tmp.pomidory != null)) { return tmp; } else { return null; } } } public class Ogorki { private static int ileNaStanie = 3; public static Ogorki dajOgorki() { if (ileNaStanie > 0) { ileNaStanie--; return new Ogorki(); } else { System.out.println("nie ma ogorkow"); return null; } } }

  9. public class Pomidory { private static int ileNaStanie = 1; public static Pomidory dajPomidory() { if (ileNaStanie > 0) { ileNaStanie--; return new Pomidory(); } else { System.out.println("nie ma pomidorow"); return null; } } } Straszne, prawda?!?

  10. Diagram klas relacja: składa się z (agregacja) relacja: dziedziczenie

  11. public class BarSzybkiejObsulugi { public static void main(String[] args) { try { Hamburger jedzonko = new Hamburger(); Hamburger drugi = new Hamburger(); } catch(HamburgerException e) { System.out.println(e.getMessage()); } } } public class Hamburger { private Mieso mieso; private Bulka bulka; private Salatka salatka; Hamburger() throws HamburgerException { mieso = new Mieso(); bulka = new Bulka(); salatka = new Salatka(); } }

  12. public class Salatka { private Pomidory pomidory; private Ogorki ogorki; Salatka() throws HamburgerException { ogorki = new Ogorki(); pomidory = new Pomidory(); } } public class Pomidory { private static int ileNaStanie = 3; Pomidory() throws HamburgerException { if (ileNaStanie > 0) ileNaStanie--; else throw new HamburgerException("nie ma pomidorow!"); } } public class Ogorki { private static int ileNaStanie = 3; Ogorki() throws HamburgerException { if (ileNaStanie > 0) ileNaStanie--; else throw new HamburgerException("nie ma ogorkow!"); } }

  13. public class Mieso { private static int ileNaStanie = 3; Mieso() throws HamburgerException { if (ileNaStanie > 0) ileNaStanie--; else throw new HamburgerException("nie ma miesa!"); } } public class Ogorki { private static int ileNaStanie = 3; Ogorki() throws HamburgerException { if (ileNaStanie > 0) ileNaStanie--; else throw new HamburgerException("nie ma ogorkow!"); } } public class HamburgerException extends Exception { HamburgerException(String message) { super(message); } }

  14. Jak to działa?? Wyjątek jest zgłaszany w razie wystąpienia nieoczekiwanego błędu. Wyjątek ten może być wychwycony przez klauzulę, która została zarejestrowana wcześniej. Jeśli wyjątek nie zostaje wychwycony, to zostaje on obsłużony przez domyślną procedurę obsługi, która zwykle wypisuje komunikat na temat miejsca, gdzie dany wyjątek został zgłoszony.

  15. Zgłoszenie wyjątku, czyli instrukcja throw i klauzula throws public int zamienCzasNa12h(int czas24h) throws NotProperTimeException{ if ((czas24h < 0) || (czas24h > 24)) throw new NotProperTimeException(); elseif (czas24h < 12) return czas24h; else return czas24h - 12; } Do zgłaszania wyjątków służy klauzula throw, która wymaga podania obiektu reprezentującego wyjątek. Wyjątki kontrolowane, zgłoszone przez daną metodę, podaje się w klauzuli throws w postaci list oddzielonych przecinkami (ściśle pilnowane).

  16. Wychwycenie wyjątku, czyli blok try i klauzule catch i finally public static void main(String[] agrs) { int czas = 19; try { int nowyCzas = zamienCzasNa12h(czas); } catch (NotProperTimeException e) { System.out.println("nie podales wlasciwego czasu"); } finally { System.out.println("Ten fragment kodu wykonuje się zawsze!"); } }

  17. Kod, który może generować wyjątek umieszczamy w bloku try. Po bloku try występują klauzule catch, które są przeszukiwane po wystąpieniu wyjątku w bloku try w celu rozpoznania wyjątku. Jeśli wyjątek zostanie rozpoznany zostaje on wyłapany przez catch i wykonywane są instrukje przeyporządkowane danej klauzuli catch. Jeśli wyjątek nie zostanie rozpoznany przez żadną klauzulę catch jest on propagowany na zewnątrz bloku try. Po bloku try i klauzulach catch może występować klauzula finally. Jeśli występuje, to jest ona wykonywana zawsze po wszystkich czynnościach związanych z obsługą klauzul catch niezależnie od tego, czy wyjątek został wygenerownay i wychwycony, czy nie wychwycony, czy blok try zakończył się w wyniku przepływu sterowania, czy też w wyniku działania instrukcji break czy continue.

  18. public class Switch { private boolean state = false; public boolean read() { return state; } public void on() { state = true; } public void off() { state = false; } } public class OnOffException1 extends Exception {} public class OnOffException2 extends Exception {} public class OnOffSwitch { private static Switch sw = new Switch(); public static void f() throws OnOffException1,OnOffException2 {} public static void main(String[] args) { try { sw.on(); f(); } catch(OnOffException1 e) { System.err.println("OnOffException1"); } catch(OnOffException2 e) { System.err.println("OnOffException2"); }finally {sw.off(); } } } finally - posprzątaj po sobie!!

  19. Wyjątki w Javie dzielimy na: • kontorlowane (checked exceptions) - kompilator jest w stanie sprawdzić, że każda metoda zgłasza tylko te wyjątki, które są jawnie wymienione w jej deklaracji. • niekontrolowane (uncheckcked exceptions) - standardowe wyjątki zgłaszane przez system wykonawczy (są podklasami klas RuntimeException i Error). Każda metoda może je zgłosić i nie musi to być uwzględnione w jej kontrakcie.

  20. relacja: dziedziczenie

  21. KlasyRuntimeException - niektóre wyjątki • ArthimeticExceptionextendsRuntimeExceptionbłąd operacji arytmetycznej (np. dzielenie przez 0) • ClassCastException extendsRuntimeExceptionpróba nieprawidłowej konwersji typu • IllegalArgumentException extendsRuntimeExceptionprzekazanie do metody niewłaściwego argumentu • IndexOutOfBoundsExceptionextendsRuntimeExceptionpróba odwołanie się do tablicy (luba napisu) poza poprawnymi granicami indexu • NegativeArraySizeException extendsRuntimeExceptionpróba utworzenia tablicy o ujemnym rozmiarze • NullPointerExceptionextendsRuntimeExceptionużycie null do wywołania metody lub uzyskania dostpu do pola obiektu; otrzymanie argumentu null przez metodę, która nie akceptuje referencji null. RuntimeException - wyjątki, o które powinien zadbać programista, wynikają najczęściej z jego przeoczeń.

  22. KlasyError - niektóre wyjątki • OutOfMemoryError extends VitrualMachineErrorbrak pamięci • StackOverfowError extends VirtualMachineErrorprzpełnienie stosu (np. z powodu nieskończonej rekurencji) • NoSuchFieldError extends IncomaptibileClassChangeErrorw klasie lub interfejsie nie znaleziono określonego pola • NoSuchMethodError extends IncomaptibileClassChangeError w klasie lub interfejsie nie znaleziono określonej metody • AbstractMethodErrorextends IncomaptibileClassChangeErrorwywołanie metody abstrakcyjnej (tylko w szczególnych okolicznościach) • ClassFormatError extends LinkageErrorładowana klasa lub interfejs ma niewłaściwy format (np. uszkodzenie pliku) Error - wyjątki, które sygnalizują poważne, w większości nienaprawialne błędy. Nie powinny być one przechwytywane i obsługiwane.

  23. Konstruktory Wyjątków Standardowo wyjątki zawierają cztery konstruktory (są to tak naprawdę konstruktory klasy Throwable, po której dziedziczą wszystkie wyjątki): • Throwable() - bezparametrowy , ustawaiający detail message (opis wyjątku) na null • Throwable(String message) - przyjmuje napis message jako detail message wyjątku (można go uzyskać od wyjątku za pomocą metody getMessage(). • Throwable(Throwable cause) - konstruuje nowy wyjątek na podstawie starego, przejmując od niego detail message i call stack trace (miejsce wywołania na stosie); wykorzystujemy ten konstruktor, gdy przechwytujemy jeden wyjątek aby rzucić następny (exception chaining), lecz inny (ze względu na np. zmianę warstwy abstrakcji) • Throwable(String message, Throwable cause) - jak wyżej, tyle że podmienia detail message na message.

  24. Co może nieść ze sobą wyjątek? class NotProperTimeException extends Exception { private int zlyCzas; NotProperTimeException() {} NotProperTimeException(String s) { super(s); } NotProperTimeException(String s, int czas) { super(s); zlyCzas = czas; } public int getZlyCzas() { return zlyCzas; } } Wyjątki mogą również dostarczać więcej informacji o występujących błędach. Wszystko zależy od tego jak my je zaprojektujemy.

  25. public int zamienCzasNa12h(int czas24h) throws NotProperTimeException{ if ((czas24h < 0) && (czas24h > 24)) throw new NotProperTimeException("zla liczba", czas24h); elseif (czas24h < 12) return czas24h; else return czas24h - 12; } public static void main(String[] agrs) { int czas = 19; try { int nowyCzas = zamienCzasNa12h(czas); } catch (NotProperTimeException e) { System.out.println(e.getMessage() + " zły agrument: " + e.getZlyCzas()); } }

  26. Użyteczne metody klasy Throwable • String getMessage() - zwraca napis podany kontruktorowi wyjątku Exception • String toString() - zwraca napis reprezentujący nazwę wyjątku (klasy wyjątku) • voidprintStackTrace() - wypisuje call stack trace czyli sekwencję metod, która została wywołana do momentu wyrzucenia wyjątku

  27. OOP a Wyjątki Kiedy korzystamy z virtualności metody (overriding a method) możemy wyrzucać wyjątek takiego typu (lub jego podtypu), który został zadeklarowany przez klauzule throws w klasie bazowej tej metody.

  28. Co można zrobić z wyjątkiem?? • wychwycić i obsłużyć • wychwycić i przekształcić na inny wyjątek zadeklarowany w klauzuli naszej metody (exception chaining) • wymienić ten wyjątek w klauzuli throws naszej metody i pozwolić na jego propagację do miejsca wywołania naszej metody, nie zajmując się jego obsługą (chyba że w klauzuli finally)

  29. Konwencje, czyli nawyki dobrego programowania • throw new Exception();zawsze tworzyć instancje obiektów w momencie ich zgłaszania - ułatwia to odnalezienie miejsca na stosie, w którym zgłoszono wyjątek • class MyException extends Exception {}własne tworzymy rozszerzając klasę Exception, a nie Throwable, tworząc z nich wyjątki kontrolowane - musimy je dekalrować przy definicjach funkcji i nie pojawiają się nie wiadomo skąd. • catch(Error e) {} NIEnie przechwytujmy wyjątków klasy Error, ponieważ oznaczają one najczęściej nienaprawialny błąd. • catch(Exception e) {} NIEnie przechwytujmy wszystkich możliwych wyjątków klasy Exception, starajmy się przechwytywać wyjątki jak najkonkretniejszych typów.

  30. Używać wyjątków czy nie, oto jest pytanie???

  31. Use exceptions to: • Handle problems at the appropriate level. (Avoid catching exceptions unless you know what to do with them). • Fix the problem and call the method that caused the exception again. • Patch things up and continue without retrying the method. • Calculate some alternative result instead of what the method was supposed to produce. • Do whatever you can in the current context and rethrow the same exception to a higher context. • Do whatever you can in the current context and throw a different exception to a higher context. • Terminate the program. • Simplify. (If your exception scheme makes things more complicated, then it is painful and annoying to use.) • Make your library and program safer. (This is a short-term investment for debugging, and a long-term investment for application robustness.)

  32. Nie używać wyjątków do oczekaiwanych i zwykłych sytuacji, np. czytając strumień danych, wiadomo że ten strumień się kiedyś skończy (jest to normalne) try { while (true) { process(stream.nrext()); } } catch(StreamEndException e) { stream.cleose(); } while (!stream.eof()) process(stream.next()); stream.close();

  33. RzutowanieiOperatorinstanceof

  34. Dwa słowa o konwersjach Konwersje występują: • przy operatorach przypisania • w wyrażeniach • przy przekazywaniu parametrów

  35. Konwersje niejawne typów pierwotnych • występują automatycznie • każdą zmienną liczbową można przypisać zmiennej która obejmuje szerszy zakres wartości. • char ==> int • float ==> double • int ==> float • mogą powodować utratę dokładności (nie zakresu)duży long ==> float =(rzutowanie)=> long

  36. Konwersje jawne typów pierwotnych (rzutowanie) • występują za pomocą operatora rzutowaniaint x;long y = 100L;x = (int) y; • mogą powodować utratę zakresu (double ==> float, nieskończoność) i dokładności • zmiennopozycyjna ==> całkowitoliczbowa (zaokrąglenie w stronę 0) • całkowitoliczbowa ==> całkowitoliczbowa (obcięcie najstarszych bitów)

  37. Diagram klas relacja: dziedziczenie

  38. Konwersje niejawne referencji • obiekt będący instacją jakiejś klasy jest też instancją każdego z jej nadtypów. Referencję do niego można zatem użyć w każdym kontekście wymagającym referencji do któregokolwiek z nadtypów. • W naszym przykładzie możemy użyć referencji typu Czekolada do obiektu typu CzarnaCzekoladaCzekolada pychotka = new CzarnaCzekolada(); • dygresja: referencję null możemy przypisać każdej zmiennej referencyjnej. • Tą konwersję nazywamy konwersją w górę (upcasting) lub bezpiecznąkonwersją.

  39. Konwersje jawne referencji (rzutowanie) • a teraz chcemy z powrotem:CzarnaCzekolada moja = (CzarnaCzekolada) pychotka; • tą konwersję nazywamy konwersją w dół (downcasting) lub niebezpiecznąkonwersją. • A jak się pomylimy i pychotka tak naprawdę nie jest typu CzarnaCzekolada to zostanie zgłoszony wyjątek ClassCastException

  40. A co jak nie wiemy którego z podtypów danej klasy jest dany obiekt, a koniecznie musimy go zrzutować? Przecież znamy wyjątki!Możnaby próbować rzutować na każdy typ po kolei i przechwytywać wyjątek ClassCastException i próbować z następnym typem aż do udanej konwersji. Ale czy to takie eleganckie?? NIE!! Nie dość że nieeleganckie to jeszcze jest przejawem złego stylu programowania!!TO NIE JEST DOBRE MIEJSCE NA UŻYCIE WYJĄTKÓW

  41. Operator instanceof public void zjedz(Czekolada pychotka) { if (pychotka instanceof CzarnaCzekolada) { CzarnaCzekolada moja = (CzarnaCzekolada) pychotka; // wykorzystanie funkcjonalności klasy CzarnaCzekolada } else { BialaCzekolada moja = (BialaCzekolada) pychotka; //wykorzystanie funkcjonalności klasy BialaCzekolada } } Uwaga: w powyższym przykładzie operator instanceof zwróci również true, gdy obiekt będzie tak naprawdę obiektem klasy CzarnaCzekoladaZOrzeszkami, będącą podklasą klasy CzarnaCzekolada.

  42. relacja: składa się z (agregacja) relacja: dziedziczenie

  43. public abstract class AbstractBody { public abstract void paint(Graphics display); } public class CialoGora extends AbstractBody { public void paint(Graphics display) { //tu się rysuje ciało na równi } } public class CialoPochylnia extends AbstractBody { public void paint(Graphics display) { //tu się rysuje ciało na pochylni } } public class Rownia extends AbstractBody { public void paint(Graphics display) { // tu się rystuje równia } }

  44. public class Plansza extends Panel{ private Vector items; Plansza() { items = new Vector(); items.addElement( new Rownia()); items.addElement( new CialoGora()); items.addElement( new CialoPochylnia()); } public void paint(Graphics display) { for (int i = 0; i < items.size(); i++) { ((AbstractBody)(items.elementAt(i))).paint(display); } } }

  45. Wykorzystane materiały • "Java TM" Ken Arnold i James Gosling • "Thinking in Java" 3 wydanie, Bruce Eckel • Kursy Javy firmy Sun • Java API Documentation http://java.sun.com/j2se/1.4.1/docs/api/index.html • "Wzorce Projektowe" Referat, Piotr Pycia • "Klasy Kolekcji" Referat, Tomasz Wilczyński • własna wyobraźnia

More Related