Úvod do programovacích jazyků (Java) Michal Krátký Katedra informatiky VŠB Technická univerzita Ostrava Úvod do programovacích jazyků (Java), 2006/2007 c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 1/27
(Exceptions) 1/15 Pro ošetření chyb poskytuje Java mechanismus zvaný výjimky (Exceptions): Když nastane v programu chyba, program vygeneruje výjimku. Běh programu je přerušen a runtime hledá kód ošetřující příslušný typ chyby exception handler. Výjimka Výjimka je událost, která nastane při vykonávání programu, která přerušení standardní běh programu. Objekt nesoucí informaci o události je také nazýván výjimka. c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 2/27
, příklad 2/15 public s t a t i c void main ( S t r i n g [ ] args ) { t r y { i n t c = I n t e g e r. p a r s e I n t ( args [ 0 ] ) ; while ( c > 0) System. out. p r i n t l n ( args [ 1 ] ) ; catch ( ArrayIndexOutOfBoundsException e ) { System. e r r. p r i n t l n ( " Chybi argument " ) ; catch ( NumberFormatException e ) { System. e r r. p r i n t l n ( " \ " " + args [ 0 ] + " \ " neni cele c i s l o " ) ; Usage: java Example 3 xyz c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 3/27
3/15 Když nastane výjimka: Je vytvořen objekt výjimky, který obsahuje informace o výjimce (typ, stav programu,... ). Běh programu je přerušen. Runtime hledá kód ošetřující chybu. Objekt výjimky je vždy instance podtřídy třídy java.lang.throwable. Existuje mnoho standardních výjimek. Můžeme vytvářet vlastní výjimky. Výjimka je vytvořena konstrukcí throw exception. Kód zachycující výjimku se nazývá exception handler (catch). Výběr handleru závisí na typu objektu výjimky. c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 4/27
4/15 Zachytávání výjimek se skládá ze tří bloků: try, catch a finally Syntaxe: t r y {... catch (... ) {... catch (... ) {... f i n a l l y {... Za try blokem musí následovat nejméně jeden blok catch nebo finally. c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 5/27
, blok try 5/15 Syntaxe: t r y {... / / p r i k a z y Blok try definuje platnost handleru. Pokud výjimka nastane v bloku try, výjimka je ošetřena příslušným handlerem asociovaným s tímto blokem. c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 6/27
, blok catch 7/15 Syntaxe: catch ( SomeThrowableObject variablename ) {... / / p r i k a z y Za try může nasledovat několik bloků catch, ale nejvýše jeden blok finally. Třída SomeThrowableObject je podtřída java.lang.throwable. Deklaruje typ výjimky, kterou může handler zachytávat. Proměnná variablename je jméno výjimky na které se můžeme v kódu odkazovat. Platnost této proměnné je v bloku try. Proměnná může být použita jako jiné lokální proměnné, např. variablename.getmessage(); Konvence: Často c 2006 tuto Michal proměnnou Krátký Úvod pojmenováváme do programovacích jazyků e. (Java) 7/27
, blok catch 8/15 Blok catch obsahuje posloupnost příkazů vykonávaných pokud je handler vyvolán. Pokud v bloku try nenastane žádná výjimka, není vykonán žádný blok catch. Jestliže v bloku try nastane výjimka typu T a jestliže existuje blok catch ošetřující výjimku typu T (nebo její nadtřídu), pak je tento blok vykonán. Jestliže existuje více než jeden handler ošetřující výjimku typu T, pak je použit první handler. Jestliže takový handler neexistuje, je hledán jiný nadřazený blok try (např. v metodě odkud byla volána metoda s původním blokem try). Poznámka: Výjimka může být vyvolána kdekoli, dokonce i v bloku catch. c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 8/27
, blok catch 9/15 Typické použití handleru: t r y {... catch ( A r i t h m e t i c E x c e p t i o n e ) { System. out. p r i n t l n ( " Osetreni A r i t h m e t i c E x c e p t i o n : e. getmessage ( ) ) ; catch ( IOException e ) { System. out. p r i n t l n ( " Osetreni IOException : " + e. getmessage ( ) ) ; c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 9/27
, blok finally 10/15 Blok finally poskytuje mechanismus umožňující vykonání kódu bez ohledu na to zda v bloku try nastala nebo nenastala výjimka. Příkazy v bloku finally jsou vykonány pokud: Blok try je standardně ukončen. V bloku try nastane výjimka, která je ošetřena jedním z handlerů. V bloku try nastane výjimka, která není ošetřena žádným handlerem. t r y {... / / o t e v r i soubor a zapis do nej f i n a l l y { i f ( f i l e! = null ) f i l e. close ( ) ; c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 10/27
, metody 11/15 Metody nemusí ošetřovat všechny výjimky, mohou vyvolat výjimku k volané metodě. Pokud výjimka typu T může být vyvolána v metodě a metoda neošetřuje výjimku typu T, pak musíme specifikovat, že metoda může vyvolat výjimku typu T. K tomuto účelu použijeme klíčové slovo throw v hlavičce metody: public void r e a d F i l e ( S t r i n g filename ) throws IOException {... c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 11/27
, metody 12/15 Jestliže metoda může vyvolat více než jeden typ výjimky, musíme všechny specifikovat: public Connection openconnection ( Address addr ) throws ConnectException, UnknownAddrException {... Typ výjimky, který může metoda vyvolat je součástí veřejného rozhraní výjimky. Volající musí výjimku znát, aby ji mohli řádně ošetřit. Pokud je metod předefinována podtřídou, pak nesmí vyvolat výjimku, která není specifikována v nadtřídě. c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 12/27
, metody 13/15 Existují dva typy výjimek: runtime exceptions - výjimky, které mohou být vyvolány kdykoli, obyčejně jsou vyvolány systémem: aritmetické výjimky, výjimky ukazatelů, atd. checked exceptions - všechny ostatní výjimky (včetně uživatelsky definovaných). Překladač kontroluje zda jsou tzv. checked výjimky ošetřeny nebo specifikovány (jako vyvolávané metodou). Runtime exception nemusí být ošetřeny ani specifikovány. c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 13/27
, hierarchie výjimek 14/15 Pomocí dědičnosti můžeme vytvářet vlastní výjimky, výhody: Seskupování chybových typů. Zjemňování chybových stavů. public class StackException extends Exception { public StackException ( S t r i n g message ) { super ( message ) ; public class EmptyStackException extends StackException { public EmptyStackException ( ) { super ( " The stack i s empty. " ) ; c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 14/27
, Vytvoření výjimky 15/15 Libovolný objekt může vytvořit výjimku pomocí konstrukce: throw somethrowableobject; Konstrukce throw požaduje jako argument třídu, která je podtřídou Throwable (společný předek). public O b j e c t pop ( ) throws EmptyStackException { i f ( size = = 0 ) { throw new EmptyStackException ( ) ; Object obj = o b j e c t A t ( s ize 1 ) ; setobjectat ( s ize 1, null ) ; size ; return obj ; c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 15/27
1/6 můžeme porovnat pomocí operátorů == a!=: Výsledek operátoru == je true pokud obě reference ukazují na stejný objekt nebo jsou obě null. V jiném případě je výsledek false. Operátor!= je negací operátoru ==. Point a = new Point ( 1 0, 2 0 ) ; Point b = new Point ( 1 0, 2 0 ) ; System. out. p r i n t l n ( a = = b ) ; / / p r i n t s f a l s e Object c = a ; System. out. p r i n t l n ( a = = c ) ; / / p r i n t s t r u e c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 16/27
, equals() 2/6 Třída java.lang.object je nadtřídou všech tříd na platformě Java. public boolean equals(object obj) Tato metoda třídy java.lang.object může být použita pro porovnání dvou různých objektů. Pokud metoda není v potomcích předefinována, pak se jedná o test (this == obj). c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 17/27
, equals() 3/6 class Point { private i n t x, y ; public boolean equals ( Object obj ) { i f (! ( obj instanceof Point ) ) return false ; Point p = ( Point ) obj ; return ( x = = p. x && y = = p. y ) ; public Point ( i n t x, i n t y ) { this. x = x ; this. y = y ; c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 18/27
, equals() 4/6 Point a = new Point ( 1 0, 2 0 ) ; Point b = new Point ( 1 0, 2 0 ) ; Point c = new Point ( 3 0, 2 0 ) ; System. out. p r i n t l n ( a = = b ) ; / / p r i n t s f a l s e System. out. p r i n t l n ( a. equals ( b ) ) ; / / p r i n t s t r u e System. out. p r i n t l n ( a. equals ( c ) ) ; / / p r i n t s f a l s e c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 19/27
, kopírování objektů 5/6 Metoda clone() třídy Object vytváří kopii objektu. Můžeme použít rozhraní Cloneable. V některých případech musíme předefinovat metodu clone(). Předefinovaná metoda clone() by nikdy neměla použít operátor new. Místo toho by měla být volána metoda super.clone(), která objekt korektně vytvoří v hierarchii nadtříd. c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 20/27
, kopírování objektů 6/6 Dva typy kopií objektu: Mělká kopie (Shallow Copy) Je vytvořena pouze kopie původního objektu. Všechny instanční proměnné mají stejnou hodnotu jako původní objekt. Tzn. pokud je instanční proměnou ukazatel na objekt, pak kopie objektu obsahuje stejný ukazatel. Hluboká kopie (Deep Copy) Kopíruje původní objekt se všemi instančními proměnnými a instančími proměnnými. Tzn. změna původního objektu se nepromítne v kopii objektu. c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 21/27
1/6 Řetězec je posloupnost znaků (primitivních typů char). V API existují dvě třídy reprezentující řetězec (obě z balíku java.lang): String, StringBuffer. Všechny řetězcové literály, např. "abc", jsou reprezentovány jako instance třídy String. Tyto instance jsou konstantní, jejich hodnota nemůže být po vytvoření měněna. StringBuffer představuje proměnný řetězec. String není pole řetězců. Tzn. char[] není String a opačně. Avšak, obě třídy String a StringBuffer používají pole řetězců pro vnitřní implementaci řetězce. c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 22/27
, třída String 2/6 Nejjednodušší způsob jak vytvořit řetězec: String s = "abc"; Přestože operátor new není implicitně volán, je vytvořena instance String. Třída obsahuje celou řadu konstruktorů. char data [ ] = { a, b, c ; S t r i n g s = new S t r i n g ( data ) ; char data2 [ ] = { a, b, c, d, e, f ; S t r i n g t = new S t r i n g ( data2, 2, 3 ) ; / / t = " cde " ; c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 23/27
, třída String 3/6 Významné metody: int length() vrací délku řetězce. char charat(int index) vrací znak na specifikované pozici. boolean equals(object obj) porovnává dva řetězce. S t r i n g s = " abcdef " ; System. out. p r i n t l n ( s. l e n g t h ( ) ) ; / / 6 System. out. p r i n t l n ( s. charat ( 5 ) ) ; / / f System. out. p r i n t l n ( s. equals ( " abcdef " ) ) ; / / t r u e System. out. p r i n t l n ( s. equals ( " h e l l o " ) ) ; / / f a l s e c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 24/27
, třída StringBuffer 4/6 Třída StringBuffer implementuje proměnný řetězec. Důležité metody: int length() void setlength(int newlength) char charat(int index) void setcharat(int index, char ch) int capacity() void ensurecapacity(int minimumcapacity) c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 25/27
, třída StringBuffer 5/6 Použití třídy StringBuffer je často efektivnější než použití třídy String. Při práci s instancí String je velmi často volán operátor new. Konstruktory: StringBuffer() StringBuffer(int length) StringBuffer(String str) c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 26/27
, třída StringBuffer 6/6 Důležité metody: append - přidání řetězce na konec, insert - přidání řetězce na specifikovaný index. S t r i n g B u f f e r b = new S t r i n g B u f f e r ( " abcd " ) ; b. append ( " ef " ) ; / / b obsahuje abcdef b. i n s e r t ( 3, " ghi " ) ; / / b obsahuje abcghidef Obsah instance může být převeden na instanci String: S t r i n g s = b. t o S t r i n g ( ) ; / / abcghidef c 2006 Michal Krátký Úvod do programovacích jazyků (Java) 27/27