Kivételkezelés, beágyazott osztályok Nyolcadik gyakorlat
Kivételkezelés
Nem minden hibát lehet fordítási időben megtalálni Korábban (pl. C-ben) a hibakezelést úgy oldották meg, hogy a függvény hibakódot adott vissza, amit a hívó félnek kellett (volna) ellenőrizni Java-ban jobb megoldás: nyelvi szinten beépítették a hibakezelést
Jobban elkülönül az „igazi” kód a hibakezeléstől
Kivételkezelés
Tegyük fel, hogy valamilyen objektumon szeretnénk műveletet végrehajtani (pl. meghívni egy metódusát). Ha valami miatt a referencia nem mutat objektumra (null az értéke), akkor a programunk elszáll. Ilyen esetben érdemes kivételt dobni, amit majd valahol el is kell kapni! Kivétel dobása a throw kulcsszóval történik:
if (p == null) throw new NullPointerException();
Kivételkezelés
Kivétel dobásakor egy kivétel objektum jön létre a heap-en, a program végrehajtása megáll (az esetleges további utasítások végrehajtására nem kerül sor), majd a kivételkezelő mechanizmus veszi át az irányítást és keres egy megfelelő kivételkezelőt, amely lekezeli a hibát.
Kivételkezelés
Védett régió – a kód olyan része, amelyben kivétel keletkezhet (jelölése try kulcsszóval) Kivétel elkapása a catch kulcsszóval, megadva utána a kivétel típusát és a hibakezelő kódot
Mivel a védett régióban több különböző kivétel dobására is sor kerülhet, több catch blokkot is meg lehet adni a védett régió után
Az első alkalmas fogja lekezelni a kivételt
Előírhatunk olyan kódot is, ami mindig lefut, akár volt kivétel a védett régióban, akár nem - finally
Kivételkezelés
Kivételkezelés
Java-ban a throws kulcsszóval meg kell adni, hogy egy metódus milyen kivétel(eke)t dobhat – amennyiben a kivételeket nem kezeljük le a metódus törzsében try-catch blokkban
Ez része a metódus-deklarációnak
void f() throws NullPointerException, ClassCastException { //… }
Saját kivétel írása
Származtatni kell az Exception osztályból
Két konstruktora van (a default és ami egy String-et vár)
Utóbbinál a String paramétert fel lehet használni egy üzenet átadására, amiből később kideríthetjük a hiba okát
public class SajatKivetel extends Exception { public SajatKivetel(String uzenet) { super(uzenet); } } Üzenet lekérdezése a kivétel-objektum getMessage() metódusával lehetséges » SajatKivetel.java
Gyakoribb kivételek
ArithmeticException
ArrayIndexOutOfBoundsException
Objektumot olyan leszármazott típusra próbáltunk kényszeríteni, amelynek valójában nem példánya
IndexOutOfBoundsException
Tömb olyan indexére próbáltunk hibatkozni, ami nincs (negatív index vagy >= tomb.length)
ClassCastException
Aritmetikai műveletek során fellépő hiba (pl. nullával való osztás)
Olyan indexre próbáltunk hivatkozni, ami nincs (tömb, String vagy Vector objektumon)
NullPointerException
Objektum helyett null-ra mutatott egy referencia
RuntimeException
Olyan kivétel, melyet nem kell megadni a kivétel specifikációban (és nem kötelező try blokkba tenni sem) Azon kivételek őse, melyeket a virtuális gép dobhat normál működés közben Leszármazottai pl.:
ClassCastException, IndexOutOfBoundsException, NullPointerException, stb.
Kivételkezelés példa
» Hiba.java
Beágyazott osztályok(NestedClass)
Más osztályon belül definiált osztályok Miért?
Logikailag nagyon szorosan összetartozó osztályok csoportosítása
Magasabb szintű egységbezárás megvalósítása
Ha egy osztály csak egyetlen másik osztály számára hasznos, így a két osztályt szorosan együtt tarthatjuk
Ha B osztálynak el kell érnie A osztály adattagjait (amelyek egyébként privát láthatóságúak kellene hogy legyenek), így B-t is elrejtjük a külvilág elől
Olvashatóbb, karbantarthatóbb kód
Ha a kisebb osztályokat beágyazzuk, a kód közelebb kerül ahhoz a helyhez, ahol felhasználjuk
Beágyazott osztályok típusai
A beágyazott osztályok lehetnek statikusak (ezeket egyszerűen statikus beágyazott osztályoknak nevezzük) és lehetnek nem statikusak (ezek neve belső osztályok) A belső osztályok elérik a „körülvevő” osztály adattagjait és metódusait, a statikus beágyazott osztályok viszont – hasonlóan a statikus metódusokhoz – nem érik el ezeket
Beágyazott osztályok
A beágyazott osztályoknak ugyanúgy megadhatjuk a láthatóságát, mint bármi másnak
private, package private, protected, public
A beágyazott osztályokból keletkező .class fájl neve mindig a következő formájú:
KülsőOsztályNeve$BelsőOsztályNeve.class
Beágyazott osztályok példa
» 08.PNG » Lista.java » LMain.java