1 / 32

Objektno orijentisano programiranje

Java, izuzeci. Objektno orijentisano programiranje. Izuzeci. Java koristi izuzetke kao način signaliziranja ozbiljnih problema prilikom izvršavanja programa. Standardne klase ih intenzivno koriste.

kaoru
Download Presentation

Objektno orijentisano programiranje

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. Java, izuzeci Objektno orijentisano programiranje

  2. Izuzeci • Java koristi izuzetke kao način signaliziranja ozbiljnih problema prilikom izvršavanja programa. • Standardne klase ih intenzivno koriste. • Pošto oni nastaju kada u našim Java programima stvari krenu naopako, a pre ili kasnije tako nešto se desi, izuzetke treba uzeti u ozbiljno razmatranje kada dizajniramo i pišemo svoje programe • Razlog zašto izuzecima do sada nije posvećeno više pažnje je što je za njih potrebno razumevanje klasa i nasleđivanja

  3. Ideja koja stoji iza izuzetaka • Izuzetak obično signalizira grešku ili neki posebno neobičan događaj u programu koji zaslužuje posebnu pažnju. • Ukoliko pokušamo da rukujemo mnoštvom često neobičnih grešaka usred koda koji rukuje normalnim operacijama programa, struktura našeg programa uskoro postaje komplikovana i teška za razumevanje. • Glavna korist od izuzetaka jeste što oni razdvajaju kod koji obrađuje greške od koda koji se izvršava kada stvari teku glatko • Drugi pozitivan aspekt izuzetaka jeste što obezbeđuju način prisiljavanja da se reaguje na određene greške

  4. Izuzeci • Važna ideja koju treba shvatiti je da ne treba sve greške u programima signalizirati izuzecima – samo neuobičajene ili katastrofalne. • Npr. ako korisnik ne unese ispravan ulazni podatak, za to ne treba koristiti izuzetke, jer se radi o uobičajenom događaju. • Razlog je što rukovanje izuzecima uključuje mnogo dodatnog procesiranja, pa će program koji rukuje izuzecima većinu vremena biti znatno sporiji nego što bi morao da bude. • U Javi, izuzetak je objekat koji se kreira kada se desi abnormalna situacija u našem programu. • Taj objekat sadrži polja ( atribute ) u koja se smeštaju informacije o prirodi problema.

  5. Izuzeci • Za izuzetak se kaže da je ”izbačen” (thrown) • Objekat koji identifikuje izuzetnu situaciju se izbacuje kao argument specifičnom parčetu koda koje se piše baš da bi rukovalo tom vrstom problema. • Za kod koji prima objekat izuzetak kao parametar se kaže da ga ”hvata” (catch) • Situacije koje uzrokuju izuzetke su prilično raznovrsne, ali spadaju u 4 kategorije: • greške koda ili podataka (neispravan pokušaj kastovanja objekta, korišćenje indeksa koji je izvan granica za taj niz, deljenje integer-a nulom) • izuzeci standardnih metoda (npr. izbacivanje StringIndexOutOfBoundsException izuzetaka) • izbacivanje naših sopstvenih izuzetaka • Java greške (obično posledica greške u našem programu)

  6. Tipovi izuzetaka • Izuzetak je uvek objekat neke potklase standardne klase Throwable. To važi i za izuzetke koje sami definišemo, kao i za standardne izuzetke • Dve direktne potklase klase Throwable – klasa Error i klasa Exception – pokrivaju sve standardne izuzetke • Obe ove klase imaju potklase za specifične izuzetke Object Throwable ErrorException izuzeci koje ne treba izuzeci koje treba hvatati hvatati

  7. Error izuzeci • Izuzeci definisani klasom Error i njenim potklasama karakterišu se činjenicom da se od nas ne očekuje da preduzimamo ništa, ne očekuje se da ih hvatamo. • Error ima 3 direktne potklase: • ThreadDeath – izbacuje se kada se nit koja se izvršava namerno stopira • LinkageError – ozbiljni problemi sa klasama u našem programu, npr. nekompatibilnost među klasama ili pokušaj kreiranja objekta nepostojećeg klasnog tipa su neke od stvari koje mogu izazvati izbacivanje izuzetka ovog tipa • VirtualMachineError – ima 4 potklase izuzetaka koji se izbacuju kada se desi katastrofalni pad JVM

  8. Error izuzeci • Izuzeci koji odgovaraju objektima klasa izvedenih iz LinkageError i VirtualMachineError su rezultat katastrofalnih događaja i uslova. U takvim situacijama obično sve što mi možemo da uradimo jeste da pročitamo poruku o grešci koja se generiše kada se izbaci izuzetak, posebno u slučaju LinkageError izuzetka i da pokušamo da shvatimo šta je u našem kodu moglo da izazove problem.

  9. RuntimeException izuzeci • Za skoro sve izuzetke predstavljene potklasama klase Exception, moramo u naš program uključiti kod koji će rukovati njima ukoliko naš kod može izazvati njihovo izbacivanje • Ako metod u našem programu može da generiše izuzetak tipa koji ima Exception kao superklasu, moramo ili rukovati izuzetkom unutar tog metoda ili registrovati da naš metod može izbaciti takav izuzetak. U suprotnom, program se neće iskompajlirati • Razlog zbog kog se RuntimeException izuzeci drugačije tretiraju i kompajler dopušta da ih ignorišemo je taj što oni generalno nastaju zbog ozbiljnih grešaka u našem kodu. • U većini slučajeva možemo da uradimo malo da popravimo situaciju.

  10. RuntimeException izuzeci • Međutim, u nekim kontekstima za neke od ovih izuzetaka, to nije uvek slučaj i možda želimo da uključimo kod za njihovo prepoznavanje • Potklase RuntimeException definisane u standardnom paketu java.lang su: • ArithmeticException (npr. deljenje integera nulom) • IndexOutOfBoundsException (npr. za niz, String ili Vector objekat) • NegativeArraySizeException (pokušaj definisanja niza negativne dimenzije) • NullPointerException (korišćenje promenljive koja sadrži null u slučaju kada ona treba da sadrži referencu na objekat da bi se pozvao metod ili pristupilo atributu) • ArrayStoreException, ClassCastException, IllegalArgumentException, SecurityException, IllegalMonitorStateException, IllegalStateException, UnsupportedOperationException ( više o njima, Horton, strana 343.)

  11. Ostale potklase klase Exception • Za sve ostale klase izvedene iz klase Exception, kompajler će proveriti da li smo izvršili rukovanje izuzetkom u metodu gde je izuzetak mogao biti izbačen ili smo naznačili da metod može izbaciti takav izuzetak. Ukoliko nismo ništa od toga, kod se nece iskompajlirati • Osim nekoliko koji imaju RuntimeException kao osnovu, svi izuzeci izbačeni od metoda Javine biblioteke klasa zahtevaju odgovarajuće rukovanje.

  12. Rukovanje izuzecima • Dakle, ako naš kod može izbaciti izuzetke koji nisu tipa Error ili RuntimeException ( i njihovih potklasa – što se podrazumeva ), moramo nešto da preduzmemo povodom toga. • Kadgod pišemo kod koji može da izbaci izuzetak, imamo izbor. Možemo obezbediti kod unutar metoda za rukovanje proizvoljnim izbačenim izuzetkom, ili ga možemo ignorisati omogućujući da metod koji sadrži kod koji može izbaciti izuzetak prosledi taj izuzetak kodu koji je pozvao metod

  13. Zadavanje izuzetaka koje metod može izbaciti • Pretpostavimo da imamo metod koji može izbaciti izuzetak koji nije tipa potklase RuntimeException niti Error klase. • Neka je izuzetak npr. tipa IOException • Ako izuzetak nije uhvaćen i nije završeno sa njegovom obradom unutar metoda, najmanje što moramo da uradimo jeste da deklarišemo da može biti izbačen izuzetak. Kako se to radi? • Jednostavno se doda throws klauza u definiciju metoda • npr. • double myMetod() throws IOException{...} • double myMetod() throws IOException,FileNotFoundException {...} • Kao što prethodni primeri pokazuju, da deklarišemo da naš metod može izbaciti izuzetke, samo dodamo ključnu reč throws nakon liste parametara metoda. Zatim se navodi lista klasa za izuzetke koji mogu biti izbačeni, razdvojenih zapetama.

  14. Zadavanje izuzetaka koje metod može izbaciti • Ako neki drugi metod poziva ovaj metod, on mora da uzme u obzir izuzetke koje ovaj može izbaciti, pa ili ih obrađivati ili i on deklarisati da izbacuje izuzetke istog tipa • Ukoliko se ne uradi ni jedno ni drugo, kompajler će to utvrditi i kod se neće iskompajlirati

  15. Rukovanje izuzecima • Ako želimo da rukujemo izuzecima tamo gde se oni dese, možemo uključiti 3 vrste blokova koda u metod koji rukuje izuzecima, i to su: • try blok – obuhvata kod gde se može javiti 1 ili više izuzetaka. Kod koji može da izbaci izuzetak koji želimo da uhvatimo mora biti u try bloku • catch blok – obuhvata kod koji je namenjen da rukuje izuzecima određenog tipa koji mogu biti izbačeni u pridruženom try bloku • finally blok – uvek se izvršava pre nego se metod završi, bez obzira da li je bilo koji izuzetak izbačen u try bloku ili nije

  16. try blok • kada želimo da uhvatimo izuzetak, kod metoda koji može izbaciti izuzetak mora biti uhvaćen try-blokom. • Kod koji može izazvati izuzetke ne mora biti u try-bloku, ali onda metod neće biti sposoban da uhvati nijedan od izbačenih izuzetaka i metod mora deklarisati da može izbaciti tipove izuzetaka koji nisu uhvaćeni • try-blok čini ključna reč try za kojom sledi par vitičastih zagrada koje okružuju kod koji može izbaciti izuzetak • try{ // kod koji moze izbaciti 1 ili vise izuzetaka } • try-blokovi su neophodni i kada želimo da uhvatimo izuzetke tipa Error ili RuntimeException ( oni se lako generišu )

  17. catch blok • kod za rukovanje izuzetkom datog tipa se ograđuje catch-blokom. • catch-blok se mora nalaziti neposredno iza try-bloka koji sadrži kod koji može izbaciti taj određeni izuzetak • catch-blok se sastoji od ključne reči catch praćene jednim parametrom unutar oblih zagrada kojim se identifikuje tip izuzetka kojim blok rukuje. Ovo prati kod za rukovanje izuzetkom koji se nalazi unutar para vitičastih zagrada • try{ // kod koji moze izbaciti 1 ili vise izuzetaka }catch(ArithmeticException e){ // kod za rukovanje izuzetkom tipa ArithmeticException }

  18. catch blok • ovaj catch blok rukuje samo izuzecima tipa ArithmeticException • To povlači da je to jedina vrsta izuzetaka koja može biti izbačena u try-bloku. Ako mogu biti izbačeni i drugi, ovo se neće iskompajlirati • Generalno, parametar za catch blok mora biti tipa Throwable ili neke njene potklase. Ako klasa koju zadamo kao parametar ima potklase, od catch bloka se očekuje da procesira izuzetke tog tipa, ali i svih potklasa tog tipa

  19. Jednostavan primer • nije bitno šta radi kod, već da izbacuje izuzetak koji hvatamo • i/0 se neće iskompajlirati, da bismo izazvali deljenje nulom moramo koristiti promenljivu ( int j = 0; ) • Treća linija u try bloku može se izvršiti samo ako se ne izbaci izuzetak – što se u ovom primeru ne može desiti • Kada se izbaci izuzetak, kontrola se neposredno prenosi na prvu naredbu catch-bloka • Nakon što se catch-blok izvrši, izvršavanje se nastavlja od naredbe koja sledi za catch-blokom • Naredbe try-bloka nakon tačke u kojoj se desio izuzetak se ne izvršavaju

  20. Jednostavan primer • Ukoliko u try bloku ne dođe do izbacivanja izuzetka ( npr. promenimo j=1 ), izvršiće se čitav try-blok, a izvršavanje će se zatim nastaviti od naredbe nakon catch-bloka ( kod u catch-bloku neće se izvršavati ). • Prilikom dodavanja try-bloka postojećem kodu mora se voditi računa. try-blok se ne razlikuje od običnog bloka kada se radi o opsegu promenljivih. • Promenljive deklarisane u try-bloku dostupne su samo unutar tog bloka. Lako je moguće obuhvatiti deklaraciju promenljive try-blokom i na taj način nemarno ograničiti njen opseg i izazvati greške pri kompajliranju. • catch-blok je sam po sebi odvojen opseg od try-bloka

  21. try-catch uparivanje • try i catch blok su međusobno vezani i ne smeju se razdvajati umetanjem naredbi između njih ili čak njihovim dodatnim ograđivanjem zagradama • Ako je blok petlje takođe i try-blok, catch-blok koji sledi je takođe onda deo te petlje • Primer, varijacijom prethodnog primera: j neka nam sada bude promenljiva za kontrolu petlje i odbrojavanje je naniže tako da eventualno dobijemo deljenje nulom unutar petlje • izlaz iz programa: ... Try block entered i = 12 j = 0 Arithmetic exception caught Try block entered i = 12 j = -1 -12 Ending try block After try block

  22. Primer, nastavak • u četvrtoj iteraciji izbaci se izuzetak jer je j=0 • Međutim, nakon izvršenja catch-bloka ipak imamo još jednu iteraciju kada je j=-1 jer su i try i catch deo petlje, oni su neodvojivi • Ako želimo da se petlja završi kada se izbaci izuzetak, onda samo celu petlju stavimo u try-blok • izlaz iz takvog programa biće: ... Loop entered i = 12 j = 0 Arithmetic exception caught After try block • Sada ne dobijemo izlaz za poslednju iteraciju jer se kontrola prenosi catch bloku kada se izbaci izuzetak, a to je sada izvan petlje

  23. Višestruki catch-blokovi • Ako try-blok može da izbaci nekoliko različitih vrsta izuzetaka, možemo staviti nekoliko catch blokova za rukovanje njima nakon try-bloka • npr. try{ // kod koji moze izbaciti izuzetke... }catch(ArithmeticException e){ // kod za rukovanje ArithmeticException izuzecima }catch(IndexOutOfBoundsException e){ // kod za rukovanje Index... izuzecima } // Izvrsavanje se nastavlja ovde ...

  24. Višestruki catch-blokovi • Izuzeci tipa ArithmeticException biće hvatani prvim catch blokom, a tipa IndexOutOfBoundsException drugim. • Naravno, ako se izbaci izuzetak tipa ArithmeticException, biće izvršen samo kod tog catch bloka. Kada se on završi, izvršavanje se nastavlja naredbom nakon poslednjeg catch bloka • Redosled catch blokova može biti od značaja. Kada se izbaci izuzetak, on će biti uhvaćen prvim catch blokom čiji je parametar istog tipa kao izuzetak ili je tipa neke njegove superklase • Implikacija je da ako postoji hijerarhija, redosled catch-blokova bi trebalo da bude: najizvedeniji tip prvo, najosnovniji tip na kraju. Inače, kod se neće iskompajlirati • Jednostavan razlog za ovo je da ako catch blok za neku klasu prethodi catch bloku za klasu koja je izvedena iz prve, drugi catch blok ne može se nikada izvršiti i kompajler će utvrditi da je to slučaj.

  25. finally blok • Priroda izuzetaka je takva da se izvršavanje try bloka prekida po izbacivanju izuzetka bez obzira na značaj koda koji sledi tačku u kojoj je izuzetak izbačen • To uvodi mogućnost da izuzetak ostavi stvari u nezadovoljavajućem stanju. Npr. možemo imati otvoren fajl i pošto je izbačen izuzetak, ne izvršava se kod za zatvaranje fajla • finally-blok obezbeđuje sredstvo da ”počistimo” na kraju izvršavanja try-bloka. Finally blok koristimo kada želimo da budemo sigurni da se neki određeni kod izvršava pre kraja metoda, bez obzira koji izuzeci su izbačeni unutar pridruženog try-bloka. • finally-blok se izvršava uvek, bez obzira da li su ili ne izbačeni izuzeci za vreme izvršavanja pridruženog try bloka.

  26. finally blok • Struktura finally bloka je: finally{ // odgovarajuci kod ... } • Upravo kao i catch blok i finally blok je pridružen određenom try bloku i mora biti smešten neposredno nakon catch blokova za taj try blok. • Ako nema catch blokova, finally blok se smešta neposredno nakon try bloka. Ako to ne učinimo, program se neće iskompajlirati • Ukoliko je neka vrednost pomoću return vraćena unutar finally bloka, to poništava return naredbu koja je eventualno izvršena u try bloku

  27. Struktuiranje metoda • try{ // Kod koji moze izbaciti izuzetke ... }catch(ExceptionType1 e){ // ... }catch(ExceptionType2 e){ // ... // ako je potrebno, jos catch blokova ... }finally{ // kod koji se uvek izvrsava nakon try-bloka } • Ne možemo imati samo try-blok. Njega uvek mora da prati bar jedan od catch i finally blokova • Izuzeci koji nisu uhvaćeni, mogu biti izbačeni kodom, bilo gde u telu metoda – u kodu koji nije ograđen try-blokom

  28. Reizbacivanje izuzetaka • U mnogim situacijama, kada neki metod uhvati izuzetak, implementiranjem odgovarajuće catch klauze, pozivajući program možda mora da zna da se to desilo • Ako izuzetak koji smo uhvatili treba da prosledimo pozivajućem programu, možemo da ga reizbacimo iz unutrašnjosti catch bloka koristeći throw naredbu • npr. try{ // ... }catch(ArithmeticException e){ // obrada ovog izuzetka throw e; } • throw naredba je ključna reč throw za kojom sledi objekat izuzetak koji se izbacuje

  29. Exception objekti • Objekat izuzetak koji se prosleđuje catch-bloku može obezbediti dodatne informacije o problemu koji ga je proizveo • Pogledajmo najpre atribute bazne klase za izuzetke, Throwable, pošto će oni biti nasleđeni u svim klasama izuzetaka i time sadržani u svakom izbačenom objektu izuzetku

  30. Klasa Throwable • svaki objekat izuzetak će sadržati metode definisane u ovoj klasi pošto je klasa Throwable klasa iz koje se izvode sve klase izuzetaka • Throwable klasa ima 2 konstruktora: • podrazumevani i konstruktor koji prihvata argument tipa String. Taj String se koristi da obezbedi opis prirode problema koji je izazvao izuzetak • Objekat tipa Throwable sadrži 2 informacije o izuzetku: • poruku o grešci • zapis o steku izvršavanja u trenutku kreiranja izuzetka

  31. Stek izvršavanja • Stek izvršavanja čuva informacije o svim metodima koji su u stanju izvršenja u svakom datom trenutku • On obezbeđuje sredstvo pomoću koga se izvršenjem return-a vraća u pozivajuću tačku metoda • Zapis steka izvršavanja koji se čuva u objektu izuzetka sadrži broj linije izvornog koda gde se desio izuzetak, a zatim podatke o pozivima metoda koji neposredno prethode tački u kojoj se desio izuzetak. Pozivi metoda ( puno kvalifikovano ime metoda plus broj linije u kojoj je poziv metoda ) su uređeni tako što se najskorije pozvan metod pojavljuje kao prvi.

  32. public metodi Throwable klase • Throwable klasa ima sledeće public metode koji omogućuju da pristupimo poruci i stanju steka • getMessage() - vraća sadržaj poruke koja opisuje tekući izuzetak ( tipično sadrži puno kvalifikovano ime klase izuzetka i kratak opis izuzetka ) • printStackTrace() - ispisuje poruku i stanje steka na standardni izlaz za grešku – što je u slučaju konzolne aplikacije ekranđ • printStackTrace(PrintStream s) – isto kao prethodni metod, osim što se izlazni tok zadaje kao argument. Poziv prethodnog metoda za objekat izuzetak e je ekvivalentan sa e.printStackTrace(System.err);

More Related