Iznimke u Javi PDF
Document Details
Uploaded by Deleted User
Tags
Summary
Ovaj dokument opisuje iznimke u Java programskom jeziku. Objašnjava primjer programa bez i s obradom iznimaka, te strategije za prilagodbu njihovog rješavanja. Dokument pruža korisne informacije o java iznimkama, korištenju try-catch blokova, te njihovoj aplikaciji u programiranju .
Full Transcript
Iznimke u Javi Sadržaj Uvod u iznimke Bacanje iznimaka Primjer programa bez obrade iznimke Kreiranje vlastitih klasa koje predstavljaju iznimke Završetak rada programa nakon pojavljivanja iznimke Primjer programa...
Iznimke u Javi Sadržaj Uvod u iznimke Bacanje iznimaka Primjer programa bez obrade iznimke Kreiranje vlastitih klasa koje predstavljaju iznimke Završetak rada programa nakon pojavljivanja iznimke Primjer programa s obradom iznimke Multi-catch blok Finally blok Hijerarhija iznimaka u Javi Označene i neoznačene iznimke u Javi Uvod u iznimke Iznimke (engl. exceptions) predstavljaju problem koji nastaje tijekom izvođenja programa Upravljanje iznimkama omogućava razvoj robusnih aplikacija koje mogu nastaviti rad i nakon nastanka problema Iznimke su u Javi predstavljene klasama koje izravno ili neizravno nasljeđuju klasu java.lang.Throwable Iznimke, odnosno objekte klasa koje predstavljaju iznimke moguće je hvatati (engl. catch) i bacati (engl. throw) Moguće je i kreirati vlastite klase koje predstavljaju iznimke nasljeđivanjem određenih klasa koje predstavljaju jednu od skupina iznimaka Primjer programa bez obrade iznimke Neka je zadan sljedeći programski isječak: public class BezObradeIznimke { private static int podijeli(int djeljenik, int djelitelj) { return djeljenik / djelitelj; } public static void main(String[] args) { Scanner unos = new Scanner(System.in); System.out.print("Unesite dva broja: "); int prvi = unos.nextInt(); int drugi = unos.nextInt(); int rezultat = podijeli(prvi, drugi); System.out.println("Rezultat dijeljenja je: " + rezultat); unos.close(); } } Primjer programa bez obrade iznimke Ako se za drugi broj unese vrijednost „0”, dijeljenje nije moguće i događa se pogreška u programu opisana sljedećim opisom: Unesite dva broja: 5 0 Exception in thread "main" java.lang.ArithmeticException: / by zero at dijeljenje.BezObradeIznimke.podijeli(BezObradeIznimke.java:8) at dijeljenje.BezObradeIznimke.main(BezObradeIznimke.java:18) Navedeni opis predstavlja stazu stoga (engl. stack trace) i uključuje: Naziv iznimke: java.lang.ArithmeticException Opisnu poruku uz iznimku: / by zero Lokacija poziva programskog koda s iznimkom: at dijeljenje.BezObradeIznimke.podijeli(BezObradeIznimke.java:8) Primjer programa bez obrade iznimke U slučaju upisa tekstualnih vrijednosti u program (umjesto brojčanih), aplikacija javlja sljedeću pogrešku: Unesite dva broja: prvi drugi Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor(Unknown Source) at java.util.Scanner.next(Unknown Source) at java.util.Scanner.nextInt(Unknown Source) at java.util.Scanner.nextInt(Unknown Source) at dijeljenje.BezObradeIznimke.main(BezObradeIznimke.java:15) Kako metoda „nextInt” iz objekta klase „Scanner” očekuje unos cjelobrojne vrijednosti, a upisan je tekst, nije moguće tu vrijednost pretvoriti u cjelobrojnu i dojavljuje se pogreška Završetak rada programa nakon pojavljivanja iznimke U slučaju pojavljivanja iznimaka java.lang.ArithmeticException i java.util.InputMismatchException kao u primjeru, program završava s izvođenjem Ponekad aplikacija može nastaviti s radom (kao u slučaju aplikacije s grafičkim sučeljem), ali rezultati mogu biti nepredvidivi Svako pojavljivanje iznimke u programu može se i obraditi te time osigurati nastavak rada programa do očekivanog završetka Informacije o iznimci često se zapisuju u posebne log datoteke kako bi se naknadno mogle analizirati Primjer programa s obradom iznimke … boolean nastaviPetlju = false; U slučaju da se do { prošli primjer try { System.out.print("Unesite dva broja: "); programa int prvi = unos.nextInt(); int drugi = unos.nextInt(); proširi int rezultat = podijeli(prvi, drugi); blokovima za System.out.println("Rezultat dijeljenja je: " + rezultat); nastaviPetlju = false; obradu iznimke, } catch(InputMismatchException ex1) { program može System.out.println("Morate unijeti brojčane vrijednosti."); nastaviti s unos.nextLine(); nastaviPetlju = true; izvođenjem } catch(ArithmeticException ex2) { usprkos System.out.println("Unesite ispravne vrijednosti za dijeljenje."); pogreškama unos.nextLine(); nastaviPetlju = true; kod unosa: } } while(nastaviPetlju); … Primjer programa s obradom iznimke Obrada iznimaka obavlja se korištenjem blokova try i catch Blok „try” sadržava programski kod u kojem postoji mogućnost bacanja iznimke Blok „catch” sadržava programski kod koji se izvodi u slučaju kad se određena iznimka dogodi Blok „try” se izvodi sve do trenutka kad se baci iznimka i nakon toga se počne izvoditi programski kod u „catch” bloku (ako se dogodi iznimka) Ako se cijeli programski kod stavi u „do-while” petlju, program se izvršava bez obzira na iznimke i traži ponovni unos od korisnika u slučaju pogrešaka U slučaju da se dogodi iznimka za koju ne postoji „catch” blok, radi se o „neuhvaćenoj iznimci” koja će prekinuti izvođenje programa Multi-catch blok Od Jave verzije 7 uvedena je mogućnost korištenja i „multi-catch” bloka On omogućava da se više različitih iznimaka hvata unutar jednog „catch” bloka, a ima sljedeći način označavanja: catch (PrviTipIznimke | DrugiTipIznimke | TreciTipIznimke ex) Navedeni „catch” blok omogućava obrađivanje svih navedenih iznimaka (ili njihovih podklasa) Koristi se u slučaju da obrada više različitih iznimaka izvodi isti programski kod Može sadržavati neograničen broj tipova iznimaka Finally blok Osim blokova „try” i „catch” postoji još jedna vrsta bloka naredbi povezanog s obradom iznimaka – „finally” blok Blok „finally” se postavlja nakon „catch” bloka (ili „try” bloka, ako „catch” ne postoji) i izvodi se uvijek, bez obzira je li došlo do iznimke ili ne Primjer: try { … } catch { … } //neobavezan finally { … } Blok „finally” koristi se u slučaju kad je nakon izvođenja „try” bloka potrebno obaviti radnje poput zatvaranja datoteke ili veze s bazom podataka, koje su potrebne bez obzira je li došlo do iznimke ili ne Hijerarhija iznimaka u Javi Sve klase koje predstavljaju iznimke u Javi izravno ili neizravno nasljeđuju klasu Exception koja ima nadklasu Throwable, što je prikazano na sljedećoj slici: Hijerarhija iznimaka u Javi Kod obrađivanja iznimaka je moguće koristiti samo jedan „catch” blok koji hvata sve iznimke u Javi tako da mu se postavi tip iznimke „Throwable” – time se hvataju i svi podtipovi klase „Throwable”, odnosno sve iznimke u Javi Klasa „Exception” i njene podklase predstavljaju iznimke koje se događaju tijekom izvođenja programa i moraju se obrađivati Klasa „Error” i njene podklase predstavljaju ozbiljne pogreške unutar JVM-a i ne smiju se obrađivati – od nekih pogrešaka se program ne može oporaviti i najbolje da se prekine njegovo izvođenje Označene i neoznačene iznimke u Javi U Javi postoje dvije vrste iznimaka: označene (engl. checked) i neoznačene (engl. unchecked) Java kompajler postavlja posebne zahtjeve na obrađivanje označenih iznimaka Vrsta iznimke određuje se klasom koju ta iznimka nasljeđuje: Exception ili RuntimeException Klase iznimaka koje izravno ili neizravno nasljeđuju klasu RuntimeException spadaju u skupinu neoznačenih iznimaka Obično označavaju pogreške u programima Primjer iznimaka: ArrayIndexOutOfBoundsException, ArithmeticException, ClassCastException, NullPointerException itd. Označene i neoznačene iznimke u Javi U skupinu neoznačenih iznimaka spadaju i iznimke koje izravno ili neizravno nasljeđuju klasu Error Najvažnija karakteristika neoznačenih iznimaka je ta što se takve iznimke ne moraju obrađivati (kompajler ne javlja pogrešku ako se ne navede „catch” blok) Sve iznimke koje nasljeđuju klasu Exception (ako ne izravno i klasu RuntimeException) nazivaju se označenim iznimkama Označavaju uvjete kod izvođenja programa koje nisu pod izravnom kontrolom programa, na primjer kad ne postoji datoteka koju program otvara i slično Označene iznimke moraju se obrađivati, u suprotnom kompajler javlja pogrešku npr. „Unhandled exception type FileNotFoundException” Bacanje iznimaka Iznimke, odnosno objekti klasa koje predstavljaju iznimke mogu se baciti korištenjem ključne riječi throw Na primjer, ako je potrebno baciti neoznačenu iznimku, kreiranje i bacanje iznimke moguće je napisati unutar jedne naredbe: throw new RuntimeException(”Pogreška u programu!”); Na sličan način moguće je baciti i označenu iznimku, samo što tu iznimku mora obraditi programski kod u kojem se ona može dogoditi Ako se ne obrađuje označena iznimka na mjestu gdje se može dogoditi, moguće je kod metode koja uključuje taj programski kod navesti da ona prosljeđuje „odgovornost” obrađivanja iznimke kodu koji poziva tu metodu korištenjem ključne riječi throws Bacanje iznimaka Na primjer, ako metoda „provjera” sadrži programski kod koji baca označenu iznimku „IOException”, ne mora je obrađivati ako je metoda označena ključnom riječju „throws” iza koje slijedi popis iznimaka (može ih biti više): public void provjera() throws IOException { … } Također, ako metoda baca iznimku korištenjem ključne riječi „throw”, nema smisla da se ta iznimka odmah i obrađuje (iako često IDE okruženje nudi tu opciju), već je potrebno koristiti ključnu riječ „throws”, npr.: try { throw new IOException(”Pogreška u radu s datotekom!”); } catch(IOException ex) {…} Kreiranje vlastitih klasa koje predstavljaju iznimke U praksi je često potrebno kreirati nove klase koje predstavljaju iznimke Vrstu iznimke (označena ili neoznačena) moguće je postaviti odabirom nadklase Exception ili RuntimeException Osim samog tipa iznimke preporuča se pisanje vlastitih konstruktora koji omogućavaju kreiranje objekta iznimke Preporuča se korištenje konstruktora bez parametara, konstruktora koji prima poruku o pogrešci, konstruktora koji prima uzročnu iznimku i konstruktora koji prima oba parametra Kreiranje vlastitih klasa koje predstavljaju iznimke public class MyException extends Exception { public MyException() { super("Dogodila se pogreška u radu programa!"); } public MyException(String message) { super(message); } public MyException(String message, Throwable cause) { super(message, cause); } public MyException(Throwable cause) { super(cause); } } Pitanja? Objektno orijentirano programiranje u Javi Sadržaj Nasljeđivanje među klasama Apstraktne klase i metode Nadklase i podklase Ključna riječ „final” Hijerarhija nasljeđivanja Definiranje sučelja Modifikator „protected” Implementiranje sučelja Ključna riječ „super” Proširenja funkcionalnosti sučelja u Javi 8 Konstruktori u podklasama Proširenja funkcionalnosti sučelja u Javi 9 Nadjačavanje metoda u podklasama Proširenja funkcionalnosti sučelja u Javi 14 Klasa „Object” Proširenja funkcionalnosti sučelja u Javi 17 Polimorfizam Nasljeđivanje među klasama Osim kreiranja novih klasa koje imaju zasebne članove, moguće je iskoristiti članske varijable i metode već postojeće klase korištenjem principa nasljeđivanja Postojeća klasa se u tom slučaju naziva nadklasa (engl. superclass), a nova klasa podklasa (engl. subclass) Podklasa kasnije može postati nadklasa drugim klasama koje nju nasljeđuju U podklasu se dodaju nove članske varijable i metode i predstavlja konkretniju implementaciju od svoje nadklase, pri čemu može mijenjati ponašanje svoje nadklase U Javi postoji klasa „java.lang.Object” koju izravno (kao prvu nadklasu) ili neizravno (preko drugih klasa) implicitno nasljeđuju sve klase u Javi (što nije potrebno posebno navoditi, jer se podrazumijeva) Java podržava samo jednostruko nasljeđivanje korištenjem ključne riječi „extends”, pri čemu svaka klasa može istovremeno nasljeđivati samo jednu nadklasu Nadklase i podklase Na primjer, ako se uvede osnovna klasa „BankovniKredit”, iz njega je moguće naslijediti klase „KreditZaAuto”, „KreditZaAdaptacijuNekretnine”, „HipotekarniKredit” itd. U tom slučaju je klasa „BankovniKredit” nadklasa, a npr. klasa „KreditZaAuto” njezina podklasa koja predstavlja konkretniju vrstu bankovnog kredita Još mogu postojati sljedeći primjeri nasljeđivanja: Nadklasa Podklase Student Apsolvent, DodiplomskiStudent Oblik Krug, Trokut, Pravokutnik, Kugla, Kocka BankovniKredit KreditZaAuto, KreditZaAdaptacijuNekretnine, HipotekarniKredit Zaposlenik NastavnickoOsoblje, PomocnoOsoblje BankovniRacun TekuciRacun, Ziroracun, DevizniRacun, KunskaStednja, DeviznaStednja Hijerarhija nasljeđivanja Odnosi između klasa i njihovo nasljeđivanje često se označavaju grafičkim hijerarhijskim strukturama koje je moguće opisati i UML Class dijagramom Takav dijagram u slučaju opisa visokoškolske zajednice može izgledati ovako: Svaka „strelica” na UML dijagramu predstavlja „je” (engl. „is a”) vezu Npr. student je član zajednice, asistent je nastavničko osoblje, a administrator je pomoćno osoblje Klasa „ClanZajednice” je „Object” Hijerarhija nasljeđivanja U slučaju hijerarhije nasljeđivanja klase „Oblik”, UML Class dijagram izgleda ovako: Osim „je” veze postoji još i „ima” (engl. „has a”) veza koja definira članske varijable klase koje su objekti drugih klasa, na primjer, klasa „Knjiga” ima članske varijable „Izdavac” i „Autor”, a klasa „Zaposlenik” ima članske varijable klasa „String” koja označava njegovo prezime ili „LocalDate” koji označava njegov datum rođenja Modifikator „protected” Osim modifikatora „public” i „private” postoji još i modifikator „protected” Modifikator „public” omogućava pristup članovima klase iz bilo koje druge klase, „private” omogućava pristup članovima klase samo unutar te iste klase, a „protected” omogućava podklasi pristup članovima nadklase i pristup svim članovima klasa koje se nalaze u istom paketu kao i klasa iz koje se tim članovima pristupa Ako se ne navede nijedan modifikator, podrazumijevani je „package private” koji omogućava pristup članovima klase samo ako su klase u istom paketu Ključna riječ „super” Ako je iz neke klase potrebno dohvatiti članove nadklase, potrebno je koristiti ključnu riječ „super” Ključna riječ „super” predstavlja referencu na nadklasu, dok ključna riječ „this” predstavlja referencu na trenutnu klasu Na primjer, ako klasa „DvodimenzionalniOblik” ima varijablu „visina”, nju je iz klase „Trokut” moguće dohvatiti naredbom super.visina Osim pristupanja varijablama iz nadklase, ključnom riječju „super” može se pozvati i konstruktor nadklase korištenjem zagrada: super() Konstruktori u podklasama Kreiranjem objekta podklase započinje ulančavano pozivanje podrazumijevanih konstruktora (ili konstruktora bez ulaznih parametara) svojih nadklasa Bez obzira navede li se ili ne, prva naredba svakog konstruktora podklase je poziv konstruktora nadklase (korištenjem naredbe „super()”) Tek nakon poziva konstruktora nadklase izvršavaju se sve ostale naredbe unutar konstruktora podklase Ako se ne navede takav raspored naredbi unutar konstruktora, kompajler javlja pogrešku Nadjačavanje metoda u podklasama Ako je potrebno nadjačati metodu iz nadklase u podklasi, potrebno je koristiti anotaciju „@Override” te napisati identičnu definiciju metode iz nadklase public class DvodimenzionalniOblik { public class Krug extends DvodimenzionalniOblik { private double visina; private double polumjer; private double sirina; @Override public double izracunajPovrsinu() { public double izracunajPovrsinu() { return visina * sirina; return Math.PI * Math.pow(polumjer, 2); } } } } Anotacije predstavljaju upute kompajleru „@Override” označava nadjačavanje metoda, u slučaju neispravnog nadjačavanja se javlja pogreška Klasa „Object” Sve klase u programskom jeziku Java izravno ili neizravno nasljeđuju klasu „java.lang.Object” Klasa „Object” sadržava niz metoda koje se često nadjačavaju (engl. override) kako bi se definiralo novo ponašanje klase, od čega su najvažnije: Naziv metode Opis equals Služi za uspoređivanje dvaju objekata i vraća „true” ako su objekti jednaki ili „false” ako nisu. U defaultnoj implementaciji uspoređuju se reference objekata, a ako je potrebno uspoređivati vrijednosti, onda je tu metodu potrebno nadjačati. hashCode Služi za definiranje algoritma izračunavanja sažetka objekta koja se koristi za optimizirano dohvaćanje objekata iz raznih struktura. toString Služi za definiranje String oblika objekta, pri čemu u defaultnoj implementaciji ispisuje oznaku reference na objekt. clone Služi za definiranje načina izrade kopije objekata (shallow ili deep copy). wait, notify, notifyAll Koriste se za rad s nitima i sinkronizaciju među njima. Polimorfizam Omogućava „općenito programiranje” umjesto „specifičnog programiranja” Korištenjem koncepata polimorfizma može se dizajnirati sustav koji je lako proširiv Konkretni tipovi objekata mogu se određivati tek prilikom izvođenja programa i ne trebaju biti poznati kod pisanja i prevođenja Na primjer, svi objekti čije klase imaju zajedničku nadklasu mogu se spremiti u jedno zajedničko polje, s time da se kod izvođenja programa mogu pozivati specifične metode za svaku od podklasa iz kojih su kreirani objekti Objekt podklase može se tretirati kao objekt klase ako se nad njim izvrši „cast” operacija i u tom slučaju može koristiti samo metode iz nadklase, npr. Trokut trokut = new Trokut(); ((Oblik) trokut).metodaIzKlaseOblik(); Apstraktne klase i metode Apstraktne klase nisu predviđene da se iz njih kreiraju objekti, već su prvenstveno namijenjene za nasljeđivanje u drugim klasama Objekte iz njih nije moguće kreirati jer se radi o „nedovršenim klasama” koje se moraju dovršiti nasljeđivanjem u podklasama Označavaju se ključnom riječju „abstract”, npr. public abstract class Oblik {…} Apstraktne klase mogu osim „običnih” metoda sadržavati i apstraktne metode Ako klasa ima barem jednu apstraktnu metodu, automatski mora biti apstraktna (u suprotnom kompajler dojavljuje pogrešku) Apstraktna metoda također se označava ključnom riječju „abstract”, na primjer: public abstract double izracunajPovrsinu(); Apstraktne metode su specifične po tome što ne sadrže tijelo metode Apstraktne klase i metode Tek kad se u podklasama koje nasljeđuju apstraktnu klasu implementiraju sve apstraktne metode, tad je moguće kreirati objekte iz takvih klasa Prilikom implementacije apstraktnih metoda unutar podklasa potrebno je koristiti anotaciju „@Override” Ako klasa koja nasljeđuje apstraktnu klasu ne implementira sve apstraktne metode iz nadklase, ona također mora biti apstraktna Apstraktne klase ne moraju nužno sadržavati apstraktne metode, ali se svejedno moraju naslijediti da bi se mogli kreirati objekti iz njih Apstraktne klase mogu sadržavati i vlastiti konstruktor koji se poziva unutar konstruktora podklase Ključna riječ „final” U slučaju da je potrebno spriječiti daljnje nasljeđivanje neke klase, kod njezine definicije potrebno je koristiti ključnu riječ „final”, npr. public final class Krug extends DvodimenzionalniOblik Slično vrijedi i za metode, u slučaju da je potrebno spriječiti daljnje nadjačavanje neke metode u podklasama, potrebno je također koristiti ključnu riječ „final”: public final double izracunajOpsegKruga(); Metode koje su označene modifikatorom „private” ne mogu se pozivati izvan klase u kojoj se nalaze, pa su samim time implicitno označene i modifikatorom „final” Slično vrijedi i za metode zajedničke za sve objekte, označene modifikatorom „static” Ključnom riječju „final” označavaju se i konstantne vrijednosti, npr. public static final String NAZIV_DRZAVE = ’’Hrvatska’’; Definiranje sučelja Omogućavaju da klase koje se međusobno ne nasljeđuju implementiraju zajedničku skupinu metoda Time se postiže „standardiziranje” načina komunikacije među klasama Sučelja opisuju koje sve „operacije” se trebaju moći obavljati, ali ne sadrže nužno i njihovu implementaciju Definicija sučelja uključuje ključnu riječ „interface”, a naziv samog sučelja mora označavati neko svojstvo, npr. public interface Elektricno { void ukljuci(); } Sučelja osim metoda mogu sadržavati i konstantne vrijednosti, a svi članovi sučelja moraju biti „public” Implementiranje sučelja Svaka klasa koja implementira određeno sučelje mora implementirati sve metode koje nemaju svoje tijelo (slično kao i kod apstraktnih klasa i metoda) Za razliku od nasljeđivanja gdje je moguće naslijediti samo jednu klasu, svaka klasa može implementirati više sučelja Prilikom implementiranja sučelja klasa mora koristiti ključnu riječ „implements”, na primjer: public class ElektricnaGitara extends Gitara implements Elektricno U slučaju da klasa ne implementira sve metode iz sučelja koje implementira, klasa mora biti apstraktna U Javi postoje i neka sučelja koja nemaju nijednu metodu i služe za označavanje određenog svojstva klase, npr. „Serializable” označava da se objekti neke klase mogu ispravno serializirati (pretvoriti u „String” oblik i npr. zapisati u datoteku ili poslati nekom udaljenom servisu putem interneta) Proširenja funkcionalnosti sučelja u Javi 8 Prije Jave 8 sučelja su mogla sadržavati samo javne metode bez implementacije Od Jave 8 sučelja mogu sadržavati i podrazumijevane implementacije metoda koje se označavaju s ključnom riječju „default” Klasa koja implementira sučelje s „default” metodom može koristiti tu podrazumijevanu implementaciju ili je nadjačati i definirati vlastitu implementaciju Primjer „defaultne” implementacije metode: public interface PracenjeVremena { default public String dohvatiDatumVrijeme() { LocalDateTime localDateTime = LocalDateTime.now(); return localDateTime.format(DateTimeFormatter.ofPattern("dd.MM.yyyy. HH:mm:ss")); } } Proširenja funkcionalnosti sučelja u Javi 8 Osim podrazumijevanih implementacija metoda u Javi 8 je omogućeno korištenje i statičkih metoda unutar sučelja Statičke metode sadrže zajedničku logiku za sve objekte klase koja implementira takvo sučelje i mogu se koristiti izravno iz same klase, bez potrebe za kreiranjem objekata, npr. public interface Provjera { public static boolean provjeriPrazanString(String tekst) { if (tekst == null || tekst.isEmpty()) { return true; } else { return false; } } } Proširenja funkcionalnosti sučelja u Javi 8 Java 8 još uključuje i funkcionalna sučelja koja omogućavaju korištenje lambda izraza Svako sučelje koje sadrži samo jednu apstraktnu metodu naziva se funkcionalnim sučeljem Moguće je napisati vlastita funkcionalna sučelja ili koristiti neka koja već postoje u Javi (npr. „Comparator”, „ActionListener”, „Runnable” ili slično) Kod funkcionalnog programiranja potrebno je specificirati što je potrebno napraviti, a ne kako Na primjer, umjesto računanja sume elemenata u cjelobrojnom polju pomoću petlje, korištenjem funkcionalnog programiranja i interne iteracije po elementima moguće je sumu izračunati korištenjem znatno manje naredbi Lambda izrazi omogućavaju pisanje skraćene notacije za kreiranje anonimnih metoda koje kompajler automatski prevodi u anonimne klase Anonimne klase su one klase čije tijelo se definira prilikom instanciranja objekta te klase Proširenja funkcionalnosti sučelja u Javi 8 Na primjer, ako je potrebno kreirati objekt klase koja nasljeđuje sučelje „Comparator” (koje služi za postavljanje kriterija sortiranja objekata npr. u polju), to je moguće napraviti na sljedeći način: Comparator c = new Comparator() { int compare(String s, String s2) {... } }; Sintaksa lambda funkcija se sastoji od definiranja liste parametara, nakon čega slijedi oznaka za strelicu „->” i na kraju tijelo lambda funkcije: (listaParametara) -> {naredbeLambdaFunkcije} Na primjer, sljedeća lambda funkcija prima dva cijela broja i vraća njihovu sumu: (int x, int y) -> {return x + y;} Moguće je izostaviti tipove parametara iz liste, kao i vitičaste zagrade u slučaju da postoji samo jedna naredba Proširenja funkcionalnosti sučelja u Javi 9 U Javi 9 unutar sučelja je omogućeno kreiranje i privatnih metoda unutar sučelja, kako bi se mogle koristiti unutar npr. podrazumijevanih metoda: public interface Sucelje { private void test() { System.out.println("Test"); } public static void test2() { System.out.println("Test 2"); } public default void test3() { test(); } } Proširenja funkcionalnosti u Javi 14 Zapisi (engl. records) omogućavaju definiranje tipova podataka koji su nepromjenjivi (engl. immutable) i namjena im je čuvanje podataka Za kreiranje „Person” zapisa koristi se ključna riječ record: public record Person (String name, String address) {} U tom slučaju generirao se sljedeći konstruktor: public Person(String name, String address) { this.name = name; this.address = address; } https://www.baeldung.com/java-record-keyword Proširenja funkcionalnosti u Javi 14 Osim toga su generirani javne „getter” metode koje se pozivaju na sljedeći način: person.name() person.address() U zapisima je moguće kreirati nove konstruktore te statičke varijable i metode https://www.baeldung.com/java-record-keyword Proširenja funkcionalnosti u Javi 17 Zapečaćena (engl. sealed) sučelja i klase omogućavaju definiranje koje klase se mogu implementirati ili nasljeđivati Za tu svrhu se koriste modifikatori sealed i non-sealed Primjer implementacije: public sealed interface Service permits Car, Truck { int getMaxServiceIntervalInMonths(); default int getMaxDistanceBetweenServicesInKilometers() { return 100000; } } Izvor: https://www.baeldung.com/java-sealed-classes-interfaces Proširenja funkcionalnosti u Javi 17 Slično kao i u slučaju zapečaćenih sučelja, moguće je „zapečatiti” i klase: public abstract sealed class Vehicle permits Car, Truck { protected final String registrationNumber; public Vehicle(String registrationNumber) { this.registrationNumber = registrationNumber; } public String getRegistrationNumber() { return registrationNumber; } } Izvor: https://www.baeldung.com/java-sealed-classes-interfaces Proširenja funkcionalnosti u Javi 17 Implementacija klase može izgledati ovako (nije omogućeno daljnje nasljeđivanje): public final class Truck extends Vehicle implements Service { private final int loadCapacity; public Truck(int loadCapacity, String registrationNumber) { super(registrationNumber); this.loadCapacity = loadCapacity; } public int getLoadCapacity() { return loadCapacity; } @Override public int getMaxServiceIntervalInMonths() { return 18; } } Izvor: https://www.baeldung.com/java-sealed-classes-interfaces Proširenja funkcionalnosti u Javi 17 Implementacija klase može izgledati i ovako (omogućeno daljnje nasljeđivanje): public non-sealed class Car extends Vehicle implements Service { private final int numberOfSeats; public Car(int numberOfSeats, String registrationNumber) { super(registrationNumber); this.numberOfSeats = numberOfSeats; } public int getNumberOfSeats() { return numberOfSeats; } @Override public int getMaxServiceIntervalInMonths() { return 12; } } Izvor: https://www.baeldung.com/java-sealed-classes-interfaces Pitanja? Klase i objekti u Javi Sadržaj ◦ Uvod u klase, objekte i metode ◦ Primjer klase „Account” ◦ Konvencija nazivanja klasa, objekata i metoda ◦ Kreiranje objekta klase „Account” ◦ „import” deklaracije ◦ Primitivni i referentni tipovi ◦ Pisanje konstruktora ◦ Novi „Date and Time API” u Javi 8 ◦ Primjer korištenja klase „LocalDateTime” ◦ Objekti i reference ◦ Uspoređivanje objekata Uvod u klase, objekte i metode ◦ Uvođenjem klasa definiraju se vlastiti tipovi podataka koji se mogu višestruko iskorištavati nasljeđivanjem ◦ Klasama se opisuju entiteti sustava koji imaju svoje atribute (varijable), a metodama (funkcijama) se opisuje njihovo ponašanje ◦ Na primjer, ako se želi kreirati klasa koja predstavlja bankovni račun, može se nazvati „Account” koji ima svoje atribute „naziv” i „stanje” i sadrži metode koje omogućavaju dohvat stanja računa, te uvećavanje i smanjivanje ◦ Metode za dohvaćanje vrijednosti atributa nazivaju se „get” i „set” metode (mogu se automatski generirati unutar IntelliJ-a) Primjer klase: „Account” package account; ◦ Varijabla „name” predstavlja varijablu instance, jer svaki račun (instanca/objekt klase „Account”) ima vlastiti naziv računa public class Account { ◦ Tip varijable „name” je „String” koji predstavlja niz znakova private String name; ◦ Vrijednost varijable „name” ne mijenja se „izravno”, već korištenjem metode „setName”, a dohvaća se public String getName() { pomoću metode „getName” return name; ◦ Elementi označeni modifikatorom „private” mogu } se koristiti samo unutar klase, a oni označeni s „public” mogu se koristiti i izvan klase public void setName(String name) { ◦ Parametar metode „setName” je lokalni parametar i this.name = name; može se koristiti samo unutar metode } ◦ Za razlikovanje parametra i istoimene varijable } instance koristi se modifikator ključna riječ „this” Konvencija nazivanja klasa, objekata i metoda ◦ Nazivi klasa moraju započeti velikim slovom ◦ Svaka klasa mora biti spremljena u istoimenu datoteku s ekstenzijom „.java” ◦ Nazivi objekata moraju započeti malim slovom ◦ Izbjegavati hrvatske dijakritičke znakove ◦ Koristi se „CamelCase” princip radi bolje čitljivosti ◦ Npr. ◦ „PrvaLaboratorijskaVjezba” ◦ „brojacStudenata” ◦ Nazivi metoda moraju započeti malim slovom Kreiranje objekta klase „Account” public class AccountTest { ◦ Pomoću objekta klase „Scanner” moguće je dohvaćati podatke koje unosi korisnik iz public static void main(String[] args) { konzole Scanner unos = new Scanner(System.in); ◦ Objekt klase „Account” kreira se u zasebnoj klasi koja ima „main” metodu Account mojRacun = new Account(); ◦ Objekte je moguće kreirati pozivom konstruktora (metode istog imena kao i System.out.println("Unesite naziv računa: "); klasa koja služi za kreiranje objekata) String brojRacuna = unos.nextLine(); ◦ Konstruktor se poziva ključnom riječju mojRacun.setName(brojRacuna); „new” ◦ Ako se ne napiše konstruktor unutar klase, unos.close(); kompajler generira defaultni konstruktor } (koji ne prima nikakve parametre i ne } inicijalizira varijable) „import” deklaracije ◦ Ako se unutar neke klase koriste druge klase koje nisu unutar istog paketa, potrebno ih je dodati u „import” deklaracije ◦ One se nalaze nakon deklaracije paketa, a prije deklaracije klase, npr. package account; import java.util.Scanner; public class AccountTest {… ◦ Najčešće se dodaju automatski korištenjem „auto complete” kombinacije tipke („CTRL+Space”) ili korištenjem opcije „Alt+Enter” ◦ Ako se ne koristi „import”, potrebno je koristiti puni naziv klase kod programiranja: java.util.Scanner unos = new java.util.Scanner(System.in); Primitivni i referentni tipovi ◦ Java dijeli tipove na primitivne i referentne ◦ Primitivni tipovi su naslijeđeni iz C++-a i to su redom: ◦ int, boolean, byte, char, short, long, float i double ◦ Referentni tipovi podataka su svi oni tipovi koji imaju vlastitu klasu ◦ Svaki primitivni tip ima svoju referentnu „verziju” ◦ Varijable primitivnih tipova mogu sadržavati samo jednu varijablu i automatski im se dodjeljuje početna vrijednost („0” ili „false”) ◦ Ako se referentni tipovi ne inicijaliziraju, poprimaju vrijednost „null” (ako se nad takvim objektima pozivaju metode ili dohvaćaju varijable, dogodit će se „NullPointerException”) Pisanje konstruktora ◦ Ako se napiše vlastiti konstruktor, objekte klase je potrebno kreirati korištenjem tog konstruktora (defaultni više nije moguće koristiti) ◦ Konstruktor se mora isto nazivati kao i sama klasa te nema povratni tip, npr. public Account(String name) { this.name = name; } ◦ U tom slučaju se kod poziva konstruktora mora predati parametar koji se inicijalizira ◦ Osim „ručnog” pisanja konstruktora, moguće je koristiti i automatsko generiranje pomoću opcije „Code->Generate…” Date and Time API ◦ Do Jave 7 koristile su se Date i Calendar klase koje su bile zastarjele i neintuitivne ◦ S vremenom su programeri napisali vlastiti open source library pod nazivom JodaTime koji je znatno unaprijedio korištenje datuma i vremena u Javi ◦ Java 8 uvodi novi „Date and Time API” po uzoru na JodaTime ◦ Moguće je koristiti klase samo za datum, samo za vrijeme, oboje, dan u tjednu itd. ◦ Klasa „Instant” služi za korištenje trenutnog vremena i korištenja nanosekundi od početka mjerenja 01.01.1970. godine ◦ Klasa „LocalDate” omogućava dohvat datuma koji uključuje godinu, mjesec i dan ◦ Klasa „LocalTime” omogućava rad s vremenom, a „LocalDateTime” s vremenom i datumom Primjer korištenja klase „LocalDateTime” LocalDateTime localDateTime = LocalDateTime.now(); System.out.println("Trenutni datum: " + localDateTime); System.out.println("Nakon dva tjedna: " + localDateTime.plusWeeks(2)); System.out.println("Formatirani datum: " + localDateTime.format( DateTimeFormatter.ofPattern("dd.MM.yyyy."))); Trenutni datum: 2020-10-10T12:37:29.035 Nakon dva tjedna: 2020-10-24T12:37:29.035 Formatirani datum: 10.10.2020. Objekti i reference (1) ◦ Nakon što se objekti deklariraju i ne dodijeli im se konkretna vrijednost (referenca), imaju vrijednost „null”, što se može prikazati na sljedeći način (npr. Objekti „firstDate” i „secondDate”): Objekti i reference (2) ◦ Kreiranjem objekta „firstDate”, npr. Korištenjem defaultnog konstruktora, rezervira se potrebna memorija za spremanje podataka ◦ Primitivni tipovi (npr. „int”) poprimaju vrijednost „0”, a referentni (npr. „String” poprimaju vrijednost „null”): Objekti i reference (3) ◦ Dodjeljivanjem konkretnih vrijednosti za članske varijable (npr. pomoću „setter” metoda) moguće je promijeniti inicijalne vrijednosti: Objekti i reference (4) ◦ Naredbom: secondDate = firstDate; ◦ objekti počinju dijeliti istu referencu, a samim time i iste memorijske lokacije s podacima (promjenom podataka će oba objekta imati novu vrijednost): Uspoređivanje objekata ◦ Objekti se u Javi mogu uspoređivati na dva načina: ◦ Po referencama (često se koristi pogrešno): ◦ if(firstDate == secondDate) {…} ◦ Po vrijednostima, za što je najbolje napisati svoju metodu (ili nadjačati metodu „equals”): boolean areTwoDatesEqual(Date f, Date s) { if (f.day == s.day && f.month.equals(s.month) && f.year == s.year) return true; else return false; } Pitanja?