Kivételek kezelése (exception handling) Hibakezelés old style class Szamolo { void szamol( String s, int i ) { int d; if (i!= 0) d = (i+1)/i; else if (s!= null) d = s.length(); else if (i > 10) // applikációs hiba 2 / 22 Kivételkezelés Ha a program mindenhol vizsgálja, hogy hiba volte, a kód áttekinthetetlenné válik Jobb megoldás, ha hiba esetén a program futása egy általánosabb hibakezelő részen folytatódik Megoldás: Kivételkezelés (Exception handling) Try blokk Catch blokk(ok) 3 / 22 1
A kivétel jelzése (dobása) Rendszer dobja, de mi kapjuk el Mi dobjuk és el is kapjuk class MyException extends Exception { public MyException(String s) {super(s); throw new MyException( hiba ); A dobott kivételnek a Throwable osztály leszármazottjának kell lennie Exception extends Throwable 4 / 22 A kivétel jelzése (dobása) Throwable osztály Minden Exception és Error ősoszálya Tartalma A futtatási stack aktuális állapota Egy String változó a hiba leírásával Referencia egy másik Throwable-re 5 / 22 Kivétel elkapása // Az itt keletkező kivételeket fogjuk elkapni catch (FileException e) { // Speciális kivételtípus elkapása catch (Exception e) { // Kevésbé speciális kivételtípus elkapása finally { // Ez a kód mindenképpen meghívódik, ha történt // kivétel a try-on belül, ha nem. 6 / 22 2
Rendszer kivételek Programunk futása közben a rendszer kivételekkel jelzi a futási hibákat, amelyeket ugyanúgy lekezelhetünk, mint a saját hibáinkat: null értékű hivatkozás 0-val való osztás nem megfelelő típusra való kasztolás, pl.: Object obj = Vector.elementAt(0); Cloneable c = (Cloneable)obj; biztonsági szabályok megszegése és még sok más 7 / 22 Hibakezelés kivételekkel class Szamolo { void szamol( String s, int i ) { int d = (i+1)/i; d = s.length(); if (i > 10) throw new MyException("10"); System.out.println( OK ); catch( Exception e ) { System.out.println("Baj"+e.getMessage()); 8 / 22 Kivétel elkapása magasabb szinten void szamol(string s, int i) throws MyException { int d = (i+1)/i; d = s.length(); if (i > 10) throw new MyException("10"); void Hivo() { Szamolo szam = new Szamolo( ); szam.szamol( disznolkodas", 0); System.out.print("OK"); catch( Exception e ) { System.out.println("Baj" + e.getmessage()); 9 / 22 3
Demo rendszer kivételekhez public class ExceptionDemo { public static void main(string[] args) { Object o = new Integer(5); String s = (String) o; catch (ClassCastException e) { System.out.println( Exception: ); System.out.println(e.toString); 10 / 22 Rendszer kivételek fajtái java.lang.indexoutofboundsexception Tömb elemének vagy sztring karakterének eléréséhez használt index kívül esik a határokon java.lang.classcastexception Ha egy hivatkozást olyan típusúra próbálunk kasztolni, ami nem kompatibilis az objektum tényleges típusával java.lang.nullpointerexception Null értékű hivatkozás tagfüggvényét v. attribútumát próbáltuk elérni java.lang.arithmeticexception Túlcsordulás, nullával való osztás 11 / 22 Szabványos adatbevitel 4
Szabványos adatbevitel C-ben C: scanf( %d %s, &i, &s) 123 kukucs int i; char * s; Karakterek fogadása Karakterek bufferelése CR-ig sor buffer Tokenekre bontás Beolvasott érték Token alapján string->típus konverzió Token string 13 / 22 Szabványos adatbevitel: Java InputStream System.in InputStreamReader BufferedReader readline() String int i = Integer valueof( ) intvalue() StringTokenizer nexttoken() 14 / 22 Szabványos adatbevitel: Java java.io ki/beviteli mőveletekre szolgáló csomag adatfolyamokra (stream) épít írható és olvasható folyamok Az adatcsere módjai közvetlenül a folyamokon keresztül int i = mystream.read(); Reader/Writer osztályok segítségével String{Reader,Writer InputStream{Reader,Writer Piped{Reader,Writer Filter{Reader,Writer CharArray{Reader,Writer Buffered{Reader,Writer 15 / 22 5
Szabványos adatbevitel import java.io.*; import java.util.*; // StringTokenizer BufferedReader be = new BufferedReader(new InputStreamReader(System.in)); String sor; int i; sor = be.readline(); StringTokenizer tokenek = new StringTokenizer( sor ); int i = Integer.valueOf(tokenek.nextToken()).intValue(); catch(ioexception e) { System.out.println( rossz adat ); catch(nosuchelementexception e) {System.out.println( kv ); catch(numberformatexception e) { i = 1; 16 / 22 Adatbevitel fájlból import java.io.*; import java.util.*; // StringTokenizer BufferedReader be = new BufferedReader( new FileReader(new File("be"))); String sor; int i; sor = be.readline(); StringTokenizer tokenek = new StringTokenizer( sor ); int i = Integer.valueOf(tokenek.nextToken()).intValue(); catch(ioexception e) { System.out.println( rossz adat ); catch(nosuchelementexception e) {System.out.println( kv ); catch(numberformatexception e) { i = 1; 17 / 22 Példa: idegen szó kérdező A program egy parancssorban megadott nevű fájlból egy szótárat olvas föl, és a szavakat egyenként, véletlen sorrendben kérdezgeti. A helyesen eltalált szót OK-val, a helytelent a szó kiírásával jelzi. hungarian Szótár Szotar(fájlnév) Hungarian Foreign foreign Szoteszt test main Fájl: idegen=magyar CRLF idegen=magyar CRLF idegen=magyar CRLF idegen=magyar CRLF 1..n String 1..n String 18 / 22 6
Példa: idegen szó kérdező class TMWException extends Exception { public TMWException( ) { class Szotar { String[] hungarian, foreign; int MAXW = 1000, iword, nwords = 0; Szotar( String file ) { hungarian = new String[MAXW]; foreign = new String[MAXW]; betöltés a file-ból String Hungarian() { Véletlen választás String Foreign() { pár elő 19 / 22 Betöltés fájlból FileInputStream input = new FileInputStream( file ); boolean EOF = false; while(!eof ) { karakterenkénti olvasás catch(tmwexception e) { System.err.println( Too many lines in file"); catch(eofexception e) { System.err.println("EOF Error!"); catch(filenotfoundexception e) { System.err.println( File not found ); catch( IOException e) { System.err.println( IO Error ); 20 / 22 Karakterenkénti olvasás StringBuffer buffer = new StringBuffer(); while(!eof ) { int i = input.read( ); if (i == -1) { input.close( ); EOF = true; else { switch ( (char)i ) { case '=': foreign[nw] = buffer.tostring(); buffer.setlength( 0 ); break; case '\n': hungarian[nw] = buffer.tostring(); if (++nw == MAXW) throw new TMWException(); buffer.setlength( 0 ); break; default: if (c!= '\r ) buffer.append( c ); 21 / 22 7
Főciklus: kikérdezés void test( ) { for( ; ; ) { System.out.print(szotar.Hungarian() + "="); BufferedReader be = new BufferedReader( new InputStreamReader(System.in)); String typed; typed = be.readline(); catch( IOException e ) { if (szotar.foreign().compareto(typed) == 0) { System.out.println("OK"); else { System.out.println( szotar.foreign() ); 22 / 22 8