Java Iznimke - exceptions
Iznimke - exceptions Exceptions – iznimne situacije greške korisničkog unosa greške uređaja fizička ograničenja programerske greške ... Java © - Eugen Mudnić
Exceptions Razmotrite otvaranje, čitanje, pisanje i zatvaranje datoteke ( bez mehanizma iznimki ) GET A FILENAME OPEN THE FILE IF THERE IS NO ERROR OPENING THE FILE READ SOME DATA IF THERE IS NO ERROR READING THE DATA PROCESS THE DATA WRITE THE DATA IF THERE IS NO ERROR WRITING THE DATA CLOSE THE FILE IF THERE IS NO ERROR CLOSING FILE RETURN Java © - Eugen Mudnić
Exceptions Korištenjem iznimki kod izgleda ovako try { // … } catch (ExceptionType1 identifier) { } catch (ExceptionType2 identifier) { } finally { } TRY TO DO THESE THINGS: GET A FILENAME OPEN THE FILE READ SOME DATA PROCESS THE DATA WRITE THE DATA CLOSE THE FILE RETURN IF THERE WAS AN ERROR OPENING THE FILE THEN DO ... IF THERE WAS AN ERROR READING THE DATA THEN DO ... IF THERE WAS AN ERROR WRITING THE DATA THEN DO ... IF THERE WAS AN ERROR CLOSING THE FILE THEN DO ... Java © - Eugen Mudnić
Što je exception – iznimka ? exception je Java objekt koji koji se kreira kad se u programu pojavi abnormalna situacija. exception objekt ima podatkovne članove koji pohranjuju informaciju o problemu Kaže se da je iznimka bačena (thrown). Stavlja se na stog dok se ne obradi Možete uhvatiti (catch) objekt iznimke sa specifičnim kodom Java © - Eugen Mudnić
Slijeđenje iznimki Method Calls Travel Down Exceptions Passed Up Java Runtime The main( ) method First Method Exception Thrown Here Method Calls Travel Down Exceptions Passed Up Java © - Eugen Mudnić
Četiri kategorije iznimki Greške u kodu i podacima: npr. pogrešno kastiranje objekta, indeks niza van granica niza,dijeljenje s nulom za cijele brojeve Iznimke metoda: npr. substring() metoda može baciti iznimku StringIndexOutOfBoundsException bacanje vlastitih iznimki Java greške: uslijed grešaka izvršavanja JVM koji interpretira vaš program, a koje obično nastaju zbog grešaka u kodu Java © - Eugen Mudnić
Sve iznimke su pokrivene s dvije direktne subklase klase - Throwable Tipovi iznimki Sve iznimke su pokrivene s dvije direktne subklase klase - Throwable Object Throwable Error Exception RuntimeException ... ... ... Java © - Eugen Mudnić
Iznimke tipa Error Predstavljaju iznimke za koje se ne očekuje da ih hvata korisnik Tri direktne subklase klase Error: ThreadDeath: baca se kada se namjerno zaustavi nit u izvršavanju. Kada se ne uhvati završava nit, a ne program LinkageError : ozbiljne greške unutar klasa u programu (nekompatibilnosti među klasama, pokušaj kreiranja objekta nepostojeće klase) VirtualMachineError – JVM greška Java © - Eugen Mudnić
Iznimke tipa RunTimeException Za skoro sve iznimke koje su reprezentirane subklasama klase exception potrebno je uključiti kod za njihovu obradu ili se program neće prevesti RunTimeException se tretiraju drukčije. Prevodilac dozvoljava njihovo ignoriranje. Razlog je u tome što se ove iznimke pojavljuju uslijed ozbiljnih grešaka u kodu, čija obrada ne bi mogla ništa značajno napraviti. Java © - Eugen Mudnić
Subklase od RuntimeException ArithmeticException: Pojava neispravnog aritmetičke operacije poput dijeljenja s nulom IndexOutOfBoundsException : indeks koji je izvan dozvoljenih granica za određeni objekt poput niza, stringa ili vektora NegativeArraySizeException : kada se upotrijebi negativan indeks niza NullPointerException : poziv metoda ili pristup podatkovnom članu null objekta ArrayStoreException : pokušaj dodjeljivana reference pogrešnog tipa u element niza ClassCastException: pokušaj kastiranja objekta neodgovarajućeg tipa SecurityException : prilikom ugrožavanja sigurnosnih mjera (security manager). . . . Java © - Eugen Mudnić
Rad s iznimkama Ako vaš kod može baciti iznimku koja nije tipa Error ili tipa RunTypeException (uključivši i sve subklase) imate dvije opcije: Možete osigurati kod koji će upravljati s bačenim iznimkama Ignoriranje na način da se omogući metodi koji baca pogreške da ih proslijedi pozivnoj metodi Java © - Eugen Mudnić
Specficiranje iznimki koje metoda može baciti Ako se iznimka ne hvata i rješava unutar metode, metoda mora deklarirati da može baciti iznimku: double mymethod() throws EOFException, FileNotFoundException { // Detalji koda metode (koristi java.io package klase)... // metoda ne rukuje s iznimkama koje mogu biti bačene } Lista klasa za iznimke koje mogu biti bačene Pass the buck, or decide that the buck stops here ! Java © - Eugen Mudnić
Uvijek se izvršava bez obzira na prethodne blokove Obrada iznimki Za kod u ovome bloku hvatamo iznimke (također i iznimke tipa Error ili RunTimeException) try { // … } catch (ExceptionType1 identifier) catch (ExceptionType2 identifier) { finally Kod koji obrađuje iznimku. Poziva se za ExceptionType1 ili bilo koju od subklasa (sve subklase bazne klase Throwable) Uvijek se izvršava bez obzira na prethodne blokove Java © - Eugen Mudnić
Druge varijante try { // … } catch (ExceptionType1 identifier) try { finally { Java © - Eugen Mudnić
Primjer: Ch7\01_TestTryCatch\TestTryCatch.java public class TestTryCatch { public static void main(String[] args) int i = 1; int j = 0; try System.out.println("Try block entered " + "i = "+ i + " j = "+j); System.out.println(i/j); // Divide by 0 - exception thrown System.out.println("Ending try block"); } // Catch the exception catch(ArithmeticException e) System.out.println("Arithmetic exception caught"); System.out.println("After try block"); return; Java © - Eugen Mudnić
Više o try/catch try blok je kao i svaki drugi blok što se tiče vidljivosti varijabli try i catch blokovi su vezani jedan za drugoga: example: Ch7\02_TestLoopTryCatch-1\TestLoopTryCatch.java Ch7\03_TestLoopTryCatch-2\TestLoopTryCatch.java Java © - Eugen Mudnić
Višestruki catck blokovi Ako imate catch blokove s nekoliko tipova iznimki u istoj klasnoj hijearhiji, potrebno je blokove postaviti u određeni red. Prvo najniže subklase pa redom prema najvišoj superklasi // neispravna sekvenca catch blokova // neće se prevesti try { // try block code } catch(Exception e) { } catch(ArithmeticException e) { } Java © - Eugen Mudnić
Više o finally bloku Korištenje za pospremanje (clean-up) Asociran s određenim try blokom (poput catch bloka) Može se koristiti i s try blokom koji sadrži kod koji ne baca nikakvu iznimku za kod s višestrukim break ili return elementima vrijednosti koje vratimo s return u finally bloku pregazit će bilo koji return izvršen u try bloku Java © - Eugen Mudnić
Strukturiranje metode try { // code that does // throw exceptions } catch(MyException1 e) // code to process // exception catch(MyException2 e) finally // code to execute // after the try block double doSome(int aParam) throws ExceptionType1, ExceptionType2 { // code that doesn't throw exceptions // Set of try/catch/finally blocks // . . . } Java © - Eugen Mudnić
Redoslijed izvršavanja - primjer Ch7\04_TryBlockTest-1\TryBlockTest.java Analiziraj različite sekvence izvršavanja ! Java © - Eugen Mudnić
Ugniježđeni try blokovi { // Inner try block code } catch(Exception1 e) // ... // Outer try block code // catch block code catch(Exception21 e) // Outer catch block code Moguće je dodati finally blokove ili još nivoa Java © - Eugen Mudnić
Ponovno bacanje iznimki U mnogim situacijama pozivni program treba informaciju o iznimci koja je bačena u metodi try { // Code that originates an arithmetic exception } catch (ArithmeticException e) // Deal with the exception here throw e; // Rethrow the exception to the calling program Java © - Eugen Mudnić
Exception objekt – klasa Throwable Exception objekt koji se prosljeđuje u catch blok sadržava dodatne informacije o prirodi problema Klasa Throwable je bazna klasa za sve Java iznimke klasa Throwable ima dva public konstruktora default kontruktor kontruktor koji prihvaća argument tipa String (tu može biti smještena informacija o prirodi pogreške) Java © - Eugen Mudnić
Exception objekt – klasa Throwable Objekti tipa Throwable sadržavaju dva primjerka informacije o iznimci: Poruka(message) (već smo naveli da se inicijalizira u konstruktoru) Zapis o izvršnom stogu (execution stack) u trenutku kada je iznimka kreirana (puni naziv svih pozvanih metoda, plus svaki broj linije u kojoj se poziv dogodio) Java © - Eugen Mudnić
Exception objekt – klasa Throwable Throwable klasa ima slijedeće public metode koje omogućavaju pristup zapisu poruka i stoga: getMessage() Vraća sadržaj poruke, koji opisuje trenutnu iznimku (null za većinu predefiniranih klasa) printStackTrace() Ispis poruka i stoga na standardni izlaz(ekran u konzolnim programima) printStackTrace(PrintStream s) Isto samo što se izlaz može dati kao argument Java © - Eugen Mudnić
Exception objekt – klasa Throwable metoda fillInStackTrace() će ažurirati zapis stoga za mjesto gdje se poziv iste obavlja koristite kad ponovo bacate iznimku da ažurirate zapis stoga kada je ponovo bačena (puno korisnije kod bacanje vlastite iznimke) e.fillInStackTrace(); throw e; Java © - Eugen Mudnić
Primjer korištenja Throwable informacija Ch7\05_TryBlockTest-2\TryBlockTest.java Java © - Eugen Mudnić
Definiranje vlastitih iznimki Dva osnovna razloga: Dodavanje informacije kada se dogodi neka standardna iznimka Pogreška koja se događa u vašem kodu zaslužna novog tipa iznimke Kod bacanja iznimki ima dosta općih troškova (overhead) Ako se sadržaj catch bloka često izvršava razmislite da li se sve moglo izvesti s nečim poput if-then-else Java © - Eugen Mudnić
Definiranje vlastitih iznimki Sve klase iznimki imaju Throwable kao superklasu najbolja praksa: derivirajte ih iz Exception cklase -> prevodilac će pratiti gdje je moguće bacanje i da li su hvatane ili proslijeđene korištenje RunTimeException ili neke od njenih subklasa -> bez provjere od strane prevodioca Java © - Eugen Mudnić
Definiranje vlastite klase iznimki // exception class – minimalna definicija public class DreadfulProblemException extends Exception { // Konstruktori public DreadfulProblemException(){ } // Default constructor public DreadfulProblemException(String s) { super(s); // Call the base class constructor } } Poruka pohranjena u superklasi, Exception (u stvari Throwable) bit će automatski inicijalizirana s nazivom klase. String proslijeđen u drugom konstruktoru bit će dodan nazivu klase Java © - Eugen Mudnić
Definiranje vlastite klase iznimki Što još dodati klasi iznimke ? druge konstruktore varijable instance za pohranu dodatnih informacija pristupne metode za varijable instance s dodatnim informacijama Java © - Eugen Mudnić
Bacanje vlastite iznimke DreadfulProblemException e = new DreadfulProblemException(); throw e; DreadfulProblemException e = new DreadfulProblemException("Uh-Oh"); throw e; getMessage() inaslijeđena od throwable vraća: "DreadfulProblemException:Uh-Oh" throw new DreadfulProblemException("Double trouble!"); Java © - Eugen Mudnić
Strategija upravljanja iznimkama int method2(...) throws Exception1, Exception2 { try // try block code that may // throw ArithmeticException } catch(ArithmeticException e) // Analysis code if(...) throw Exception1; else throw Exception2; void method1(...) { try int x= method2(...); } catch( Exception1 e) //handle exception catch( Exception2 e) method1 može baciti dvije vrste iznimki Java © - Eugen Mudnić
Upravljanje iznimkama primjer: Ch7\06_DesignOwnException ZeroDivideException.java TryBlockTest.java Java © - Eugen Mudnić