45
Wyjątki, rzutowanie, operator instanceof Kamil Piekarz Inforamtyka II rok, grupa V prowadzący zajęcia mgr. inż. Dominik Radziszowski

Wyjątki, rzutowanie, operator instanceof

  • Upload
    qamra

  • View
    47

  • Download
    0

Embed Size (px)

DESCRIPTION

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:. - PowerPoint PPT Presentation

Citation preview

Page 1: Wyjątki,  rzutowanie,   operator instanceof

Wyjątki, rzutowanie,

operator instanceof

Kamil PiekarzInforamtyka II rok, grupa V

prowadzący zajęciamgr. inż. Dominik Radziszowski

Page 2: Wyjątki,  rzutowanie,   operator instanceof

Wyjątki

Page 3: Wyjątki,  rzutowanie,   operator instanceof

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.

Page 4: Wyjątki,  rzutowanie,   operator instanceof

Zróbmy sobie hamburgera...

Page 5: Wyjątki,  rzutowanie,   operator instanceof

Diagram klas

D iag ram k las

Mieso Bulka

Pomidory Ogorki

Salatka

Hamburger

relacja: składa się z (agregacja)

Page 6: Wyjątki,  rzutowanie,   operator instanceof

public class BarSzybkiejObsulugi { public static void main(String[] args) {

Hamburger jedzonko = Hamburger.dajHamburgera();Hamburger drugi = Hamburger.dajHamburgera();

}}

public class Hamburger {private Mieso mieso;private Bulka bulka;private Salatka salatka;

public static 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 {

return null;}

}

}

Page 7: Wyjątki,  rzutowanie,   operator instanceof

public class Mieso {private static int ileNaStanie = 3;public static Mieso dajMieso() {

if (ileNaStanie > 0) {ileNaStanie--;return new Mieso();

}else {

System.out.println("nie ma miesa");return null;

}}

}

public class Bulka {private static int ileNaStanie = 1;public static Bulka dajBulke() {

if (ileNaStanie > 0) {ileNaStanie--;return new Bulka();

}else {

System.out.println("nie ma bulki");return null;

}}

}

Page 8: Wyjątki,  rzutowanie,   operator instanceof

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;

}}

}

Page 9: Wyjątki,  rzutowanie,   operator instanceof

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?!?

Page 10: Wyjątki,  rzutowanie,   operator instanceof

Diagram klas

D iag ram k las

Mieso Bulka

Pomidory Ogorki

Salatka

Hamburger

relacja: składa się z (agregacja)

HamburgerException

Exception

relacja: dziedziczenie

Page 11: Wyjątki,  rzutowanie,   operator instanceof

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();

}}

Page 12: Wyjątki,  rzutowanie,   operator instanceof

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!");

}}

Page 13: Wyjątki,  rzutowanie,   operator instanceof

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);}

}

Page 14: Wyjątki,  rzutowanie,   operator instanceof

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.

Page 15: Wyjątki,  rzutowanie,   operator instanceof

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();

else if (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).

Page 16: Wyjątki,  rzutowanie,   operator instanceof

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!");

}

}

Page 17: Wyjątki,  rzutowanie,   operator instanceof

Kod, który może generować wyjątek umieszczamy w 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.

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.

Page 18: Wyjątki,  rzutowanie,   operator instanceof

finally - posprzątaj po sobie!!

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(); } }}

Page 19: Wyjątki,  rzutowanie,   operator instanceof

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.

Page 20: Wyjątki,  rzutowanie,   operator instanceof

Error

Runtim eException OurExceptions

Exception

Throwable

Objec t

relacja: dziedziczenie

Page 21: Wyjątki,  rzutowanie,   operator instanceof

Klasy RuntimeException - niektóre wyjątki

• ArthimeticException extends RuntimeExceptionbłąd operacji arytmetycznej (np. dzielenie przez 0)

• ClassCastException extends RuntimeExceptionpróba nieprawidłowej konwersji typu

• IllegalArgumentException extends RuntimeExceptionprzekazanie do metody niewłaściwego argumentu

• IndexOutOfBoundsException extends RuntimeExceptionpróba odwołanie się do tablicy (luba napisu) poza poprawnymi granicami indexu

• NegativeArraySizeException extends RuntimeExceptionpróba utworzenia tablicy o ujemnym rozmiarze

• NullPointerException extends RuntimeExceptionuż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ń.

Page 22: Wyjątki,  rzutowanie,   operator instanceof

Klasy Error - niektóre wyjątki

• OutOfMemoryError extends VitrualMachineError brak 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

• AbstractMethodError extends IncomaptibileClassChangeError wywoł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.

Page 23: Wyjątki,  rzutowanie,   operator instanceof

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.

Page 24: Wyjątki,  rzutowanie,   operator instanceof

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.

Page 25: Wyjątki,  rzutowanie,   operator instanceof

public int zamienCzasNa12h(int czas24h) throws NotProperTimeException{

if ((czas24h < 0) && (czas24h > 24))

throw new NotProperTimeException("zla liczba", czas24h);

else if (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());

}

}

Page 26: Wyjątki,  rzutowanie,   operator instanceof

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)

• void printStackTrace() - wypisuje call stack trace czyli sekwencję metod, która została wywołana do momentu wyrzucenia wyjątku

Page 27: Wyjątki,  rzutowanie,   operator instanceof

OOP a Wyjątki

I temvo id n ic () th row s M yE xcep tion

A b s trac tItemab s trac t vo id n ic () th row s M yE xcep tion

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.

Page 28: Wyjątki,  rzutowanie,   operator instanceof

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)

Page 29: Wyjątki,  rzutowanie,   operator instanceof

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.

Page 30: Wyjątki,  rzutowanie,   operator instanceof

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

Page 31: Wyjątki,  rzutowanie,   operator instanceof

• 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.)

Use exceptions to:

Page 32: Wyjątki,  rzutowanie,   operator instanceof

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)

while (!stream.eof())

process(stream.next());

stream.close();

try {

while (true) {

process(stream.nrext());

}

}

catch(StreamEndException e) {

stream.cleose();

}

Page 33: Wyjątki,  rzutowanie,   operator instanceof

Rzutowaniei

Operatorinstanceof

Page 34: Wyjątki,  rzutowanie,   operator instanceof

Dwa słowa o konwersjach

jawn e(rzu towan ie )

n ie jawn e

K on w ers je

Konwersje występują:

• przy operatorach przypisania

• w wyrażeniach

• przy przekazywaniu parametrów

Page 35: Wyjątki,  rzutowanie,   operator instanceof

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

Page 36: Wyjątki,  rzutowanie,   operator instanceof

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)

Page 37: Wyjątki,  rzutowanie,   operator instanceof

B ia laC zeko lad a C zarn aC zeko lad a

C zeko lad a

Diagram klas

relacja: dziedziczenie

Page 38: Wyjątki,  rzutowanie,   operator instanceof

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ą.

Page 39: Wyjątki,  rzutowanie,   operator instanceof

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

Page 40: Wyjątki,  rzutowanie,   operator instanceof

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

Page 41: Wyjątki,  rzutowanie,   operator instanceof

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.

Page 42: Wyjątki,  rzutowanie,   operator instanceof

C ia loR own ia C ia loP och yln ia R ow n ia

A b s trac tB od y

V ec to r

P lan sza

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

Page 43: Wyjątki,  rzutowanie,   operator instanceof

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}

}

Page 44: Wyjątki,  rzutowanie,   operator instanceof

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);}

}}

Page 45: Wyjątki,  rzutowanie,   operator instanceof

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