340 likes | 455 Views
6. gyakorlat. Fájlkezelés, IO Kivételkezelés Belső osztályok. Fájlkezelés, IO. Java IO. adatfolyam alapú megközelítés (stream-ek) InputStream/OutputStream: byte-orientált IO InputStream: adatforrás-folyam OutputStream: adatnyelő-folyam
E N D
6. gyakorlat Fájlkezelés, IO Kivételkezelés Belső osztályok
Java IO • adatfolyam alapú megközelítés (stream-ek) • InputStream/OutputStream: byte-orientált IO • InputStream: adatforrás-folyam • OutputStream: adatnyelő-folyam • Reader/Writer osztályok: karakter-orientált IO unicode támogatással • konvertáló osztályok (pl. InputStreamReader)
Standard IO • standard input: System.in • standard output: System.out • standard error: System.err • a System.out és a System.err közvetlenül használhatók (ahogyan eddig is használtuk őket)
Importálás IO-hoz • importálnunk kell: import java.io.*; • amiket általában használunk belőle (az API-ban utánuk lehet nézni bővebben): • BufferedReader • InputStreamReader • FileReader • FileWriter
Billentyűzetről beolvasás • BufferedReader: szöveget olvas a karakter input-streamről • InputStreamReader: byte-okat olvas, majd karakterekké alakítja őket BufferedReader be = new BufferedReader(new InputStreamReader(System.in)); be.read(); be.readLine();
Billentyűzetről beolvasás • read(): egyetlen karaktert olvas be, és az ASCII kódjával tér vissza • readLine(): egy sort olvas be, és a beolvasott sztringgel tér vissza
Beolvasás fájlból • FileReader: karakteres fájlokat olvas • konstruktorában egy File objektumot vár • readLine(): egy sort olvas be a fájlból BufferedReader be = new BufferedReader(new FileReader(new File(”fajlnev.txt”))); be.readLine();
Kiíratás fájlba • FileWriter: karakteres fájlokat ír • szintén át kell adnunk neki egy File objektumot FileWriter ki = new FileWriter(new File(”uj.txt”)); ki.write(”szöveg”); • az IO műveletek végén a stream-eket zárjuk le! • be.close(); • ki.close();
Példaprogram • Fajlkezeles.zip (honlapomon)
Kivételkezelés fogalmai • nem derül ki minden hiba a fordítás során • kivétel: egy probléma, mely meggátolja a futást egy adott metódusban/blokkban • pl. null referencia • kivétel dobása: • az aktuális program végrehajtása megáll, kivétel „dobódik” • a kivételkezelő mechanizmus keres egy megfelelő kivételkezelőt • a kivételkezelő lekezeli a hibát, a program futása folytatódik
Kivételkezelés fogalmai • kivétel elkapása: • ha valahol kivétel dobódik, akkor feltételezzük, hogy az valahol el lesz kapva • védett régió: • a kód azon része, mely kivételeket hozhat létre • hibakezelő kód követi try{ … } catch{ … }
Kivételkezelés try { … } catch (NullPointerException e) { … } „veszélyes kód”: kivételt dobhat mi történjen, ha elkaptuk a kivételt?
Exception osztály • a kivételek mind az Exception osztályból származnak • néhány példa kivételekre: • ClassNotFoundException • DataFormatException • IOException • SQLException • ArithmeticException (pl. nullával osztás) • ArrayIndexOutOfBoundsException (tömbindexelési hibák) • FileNotFoundException • RuntimeException • …
Try, catch, finally • több catch blokk is lehet try { ... } catch (ArithmeticException e){ … } catch (IOException e){ … } catch (Exception e){ … } finally { … } • sorba nézzük a catch ágakat, mindegyiknél az adott hibát tudjuk elkapni amit a finally-ba írok, az mindenképpen lefut (függetlenül attól, dobódik-e kivétel vagy nem)
Try, catch, finally • catch (Exception e): általános kivételelkapó • a finally ág nem kötelező, de hasznos lehet stream-ek vagy kapcsolatok lezárásához, mert így mindenképpen lezárjuk őket • pl. ki.close();
RuntimeException • azon kivételek őse, amiket a virtuális gép dobhat a normál működése közben • ezen osztályból származó kivételeket nem feltétlen kell elkapni, mert ha bekövetkeznek, akkor se tudunk sok mindent kezdeni velünk (a program úgyis meghal) • ilyen pl. a NullPointerException, ArrayIndexOutOfBoundsException
Throwable osztály • az Object osztályból származik ez is • két leszármazottja van: • Exception: erről volt szó eddig • Error: fordítási időbeni- és rendszerhibák, ezekkel általában nem kell foglalkozni
Throws kulcsszó • ezzel jelzem, hogy valami (általában metódus) dobhat kivételt, viszont a kivételt nem kapom el (vagy máshol kapom el) public void beolvas() throws IOException{ } • sok esetben le sem lehet fordítani a programot a throws nélkül
Saját kivétel létrehozása • származtatni kell valamilyen létező kivétel osztályból public class SajatKivetel extends Exception{ public SajatKivetel(String message){ super(message); } }
Throw kulcsszó • kivételt dobhatunk vele (manuálisan) • Pl.: if (x<0) throw new SajatKivetel(„X negatív.”); • ne keverjük a throws kulcsszóval, ami annak jelzésére szolgál, hogy egy metódus milyen kivételt dobhat! • ha saját kivételt dobunk, azt jeleznünk kell a „throws” kulcsszóval, vagy try-catch segítségével kell lekezelni • ha egyiket se tesszük, fordítási hibát fogunk kapni
throws vs. throw public static void main(String args[]) throws SajatKivetel{ int a=3; int b=0; if(b==0)throw new SajatKivetel(„Nulla az osztó”); else System.out.println((float)a/b); } jelezzük, hogy dobhat ilyen kivételt b=0 esetén ténylegesen dobjuk is a kivételt
Példaprogramok • SajatKivetel.java (pub, 8. gyakorlat) • Hiba.java (pub, 8. gyakorlat)
Belső osztályok • osztályon vagy metóduson belüli osztályok • cél: máshol nem használt algoritmus teljes elrejtése • a belső osztályból elérhetők a „körülvevő” osztály elemei • kivéve ha a belső osztály static • egy (nem belső) osztály láthatósága csak public vagy package private lehet, a belső osztály viszont ezen felül lehet private, protected, sőt static is • nem kell őket külön fordítani
Példa belső osztályra • osztályon belüli belső osztály: public class Kulso{ … private class Belso{…} … }
Példa belső osztályra • metóduson belüli belső osztály: public void csinalValamit(){ … private class Belso(){…} … }
Belső osztály példányosítása • a tartalmazón belül ugyanúgy, mint eddig • a tartalmazón kívülről: Kulso.Belso peldany = new Kulso.Belso(); • csak nemstatikus belső osztály esetén: Kulso peldanyKulso = new Kulso(); Kulso.Belso púeldanyBelso = peldanyKulso.new Belso();
Példaprogramok • Lista.java (pub, 8. gyakorlat) • Lmain.java (pub, 8. gyakorlat)
Gyakorló feladatok • pub: 8. gyakorlathoz tartozó feladatok.txt
Szorgalmi feladat • szerda éjfélig küldhető el 3 pluszpontért nekem e-mailben Feladat: • Írj három saját hiba osztályt: mindegyik származzon az Exception osztályból, legyen default és paraméteres konsturktoruk is, ezekben az Exception osztály default, valamint az 1 db String argumentumot váró konstruktorát hívd meg • az egyik az InvalidYearException osztály: a default konstruktorban az "Érvénytelen évszám!„ szöveget add át az ős konstruktorának, a paraméteresben értelemszerűen a kapott String típusú paramétert • Legyen ugyanilyen módon létrehozva az InvalidCitizenshipException és a TooLongNameException osztály is (itt a default konstruktor a "Nem magyar állampolgár„ és a „Túl hosszú a név!” szövegeket adja át az ős konstruktorának) • Mindhárom osztály kerüljön a kivetelkezeles, azon belül a sajatkivetelek csomagba
Szorgalmi feladat • Írj egy Állampolgár osztályt, legyen a kivetelkezeles csomagban: adattagjai az adószám (egész), a név, az évszám (egész szám) és az állampolgárság (String, pl. „magyar”, „német”…) • Írj hozzá paraméteres konstruktort, mely 4 paramétert vár. A konstruktorban ellenőrizd: • hogy az évszám pozitív-e, ha nem, akkor dobj InvalidYearExceptiont • hogy a név hossza nagyobb-e 35-nél, ha igen, akkor dobj TooLongNameExceptiont a következő szöveggel: "A név túl hosszú: x karakter. Maximum 35 karakter lehet.„ (x nyilván az aktuálisan átadott paraméter hossza) • hogy az állampolgárság értéke a „magyar”-e, amennyiben nem, dobj InvalidCitizenshipExceptiont a következő szöveggel: "Hiba: az adatbázis csak magyar állampolgárságú személyek adatait tartalmazhatja!„ • Írj hozzá getter-setter metódusokat, a fentebb említett ellenőrzések a megfelelő setterekben is történjenek meg, valamint a hibadobás is
Szorgalmi feladat • A hibadobást jelezd a throws kulcsszó segítségével a megfelelő metódusok deklarációjában, a hibát elkapni az osztályban sehol sem kell • Írj egy KivételPélda osztályt, legyen ez is a kivetelkezeles csomagban: • Próbálj létrehozni állampolgár objektumokat, valamint a setterek segítségével átállítani az adattagjaikat (ez veszélyes kód, kezeld ennek megfelelően) • A keletkező hibákat kapd el, és az e.printStackTrace() hívásával írasd ki a konzolra a megfelelő információkat a hibáról • Ne felejtsd el importálni a saját hiba osztályaidat!