Dione
Z. KotalaP. Toman: Java
Predchozi (Obsah) Dalsi

13. V²jimky

V²jimka (exception) je definovßna jako udßlost, kterß nastane b∞hem provßd∞nφ programu a kterß naru╣φ normßlnφ b∞h instrukcφ. V²jimka je vyvolßna nap°φklad p°i chybnΘm otev°enφ souboru, p°i p°ekroΦenφ mezφ pole, p°i aritmetickΘ chyb∞ apod. Mechanismus v²jimek umo╛≥uje tyto chybovΘ stavy zachytit a o╣et°it. K tomu slou╛φ dvojice blok∙ try a catch, jejich╛ syntaxe je nßsledujφcφ:

   try {
      // hlφdan² blok
   } catch( t°φdaV²jimek1 jmΘnoProm∞nnΘ1 ) {
      // o╣et°enφ v²jimky
   } catch( t°φdaV²jimek2 jmΘnoProm∞nnΘ2 ) {
      // o╣et°enφ v²jimky
   }

  • Hlφdan² blok try - uzavφrß kritickou Φßst programu, kde "m∙╛e" b²t vyvolßna v²jimka.

  • ZßchytnΘ bloky catch - o╣et°ujφ v²jimky, musφ nßsledovat bezprost°edn∞ za blokem try a m∙╛e jich b²t libovoln² poΦet.

    Vyvolanß v²jimka je objekt a ka╛d² zßchytn² blok zachycuje jeden typ v²jimek (t°φdaV²jimek1, t°φdaV²jimek2). Na vyvolanou v²jimku v zßchytnΘm bloku odkazuje referenΦnφ prom∞nnß (jmΘnoProm∞nnΘ1, jmΘnoProm∞nnΘ2).

    Pokud v hlφdanΘm bloku v²jimka:

    • nenφ vyvolßna, pokraΦuje pokraΦuje program za poslednφm zßchytn²m blokem.

    • je vyvolßna, pokraΦuje program prvnφm zßchytn²m blokem, kter² o╣et°uje odpovφdajφcφ t°φdu v²jimek (viz 13.1.). Po opu╣t∞nφ zßchytnΘho bloku pokraΦuje program za poslednφm zßchytn²m blokem.

      Pozn.: HlφdanΘ a zßchytnΘ bloky je mo╛nΘ do sebe vno°ovat, tj. ka╛d² zßchytn² blok m∙╛e op∞t obsahovat dvojici blok∙ try-catch.

Priklad 13.1.
Metoda nactiBajt otev°e soubor zadanΘho jmΘna (1) a naΦte z n∞j prvnφ byte, kter² vypφ╣e na standardnφ v²stup (1) (2).

void nactiBajt(String jSouboru) {
   try {
      FileInputStream soubor = new FileInputStream(jSouboru);   // (1)
      System.out.println(soubor.read());                        // (2)

   } catch(FileNotFoundException e) {                           // (3)
      System.out.println("Soubor " + jSouboru + "nenalezen.");  // (4)
   } catch(IOException e) {                                     // (5)
      System.out.println("Chyba p°i Φtenφ souboru " + jSouboru);// (6)
   }
}
P°i pokusu otev°enφ souboru se m∙╛e stßt, ╛e tento nebude nalezen (nastane v²jimka FileNotFoundException), nap°. pokud soubor neexistuje nebo je chybn∞ zadanΘ jmΘno. Pokud tento v²jimeΦn² stav nastane, je zachycen blokem catch na °ßdce (3) a vypφ╣e se chybovß zprßva (4).

TakΘ p°i Φtenφ m∙╛e nastat chyba (v²jimka IOException), nap°. pokud soubor nenφ urΦen pro Φtenφ nebo nastane chyba za°φzenφ. Tento stav zachycuje blok catch na °ßdce (5) a vypφ╣e se chybovß zprßva (6).

Pokud v╣e prob∞hne bez problΘm∙, pokraΦuje program za zßchytn²mi bloky (metoda skonΦφ).

Pozn.: V╣imn∞te si, ╛e dφky v²jimkßm je d∙sledn∞ odd∞len "u╛iteΦn² k≤d" od k≤du, kter² pouze o╣et°uje chyby. V²jimka jednΘ t°φdy m∙╛e b²t navφc vyvolßna v hlφdanΘm bloku na n∞kolika mφstech a k o╣et°enφ postaΦuje jeden blok catch. Ve srovnßnφ s klasick²m zp∙sobem testovßnφ chyb (p°φkazem if) je zachycovßnφ chyb pomocφ v²jimek mnohem p°ehledn∞j╣φ.

13.1. T°φdy v²jimek

RodiΦovskou t°φdou v╣ech v²jimek je Throwable (z balφku java.lang), kterß mß standardn∞ dva p°φmΘ potomky:

  • Error - reprezentuje fatßlnφ chyby, kterΘ by nem∞ly b²t zachycovßny, nebo╗ se z nich nelze zotavit (chyba JVM apod.).

  • Exception - slou╛φ jako rodiΦovskß t°φda pro v╣echny ostatnφ v²jimky.

╚ßst stromu v²jimek t°φdy Exception vypadß takto:

vyjimky.gif

Dφky objektovΘ hierarchii v²jimek je mo╛nΘ zachytit vφce t°φd v²jimek v jednom catch bloku - jedna t°φda v²jimek v sob∞ zahrnuje i v╣echny potomky tΘto t°φdy.

Proto╛e v╣ak u zßchytn²ch blok∙ zßle╛φ na po°adφ, (2) je mo╛nΘ n∞kterΘ potomky zachytit zvlß╣╗ a ostatnφ nechat bloku zachycujφcφ v²jimky rodiΦovskΘ t°φdy:

Priklad 13.2.
try {
   // ...
} catch(ArithmeticException e) {
   // zachycenφ v²jimek t°φdy ArithmeticException
} catch(Exception e) {
   // zachycenφ v╣ech v²jimek t°φdy Exception , tj.
   // InterruptedException , RuntimeException ,
   // IndexOutOfBoundsException atd. (krom∞ ArithmeticException )
}

Pozn.: Programßtor si samoz°ejm∞ m∙╛e vytvo°it vlastnφ t°φdu v²jimek - staΦφ vytvo°it potomka n∞kterΘ z t°φd v²jimek z Java Core API (nedoporuΦuje se v╣ak jako rodiΦovskou t°φdu pou╛φt p°φmo Throwable).

13.2. Vyvolßnφ v²jimky

V²jimky je mo╛nΘ programov∞ vyvolßvat p°φkazem throw. Jeho syntaxe je:

   throw instanceV²jimky ;

V²jimka instanceV²jimky musφ b²t instancφ t°φdy Throwable nebo jejφch potomk∙.

Priklad 13.3.
Vyvolßnφ v²jimky t°φdy ArithmeticException se provede pomocφ:

throw new ArithmeticException();

13.3. Deklarace v²jimek

V╣echny v²jimky, kterΘ mohou v danΘ metod∞ nastat, musφ b²t zachyceny nebo deklarovßny (viz 11.2.2.), jinak p°ekladaΦ ohlßsφ chybu. (3) Druh² p°φpad znamenß, ╛e metoda p°enechßvß o╣et°enφ deklarovan²ch v²jimek volajφcφ metod∞ - dochßzφ k tzv. propagaci v²jimek (viz 13.4.). Volajφcφ metoda op∞t musφ tyto (resp. v╣echny) v²jimky zachytit nebo deklarovat.

Deklarace v²jimek se pou╛φvß zejmΘna v p°φpad∞, ╛e na danΘ ·rovni (nap°. p°φmo v knihovn∞) nenφ vhodnΘ provßd∞t o╣et°enφ v²jimky (nenφ mo╛nΘ rozhodnout, jak by m∞lo vypadat o╣et°enφ):

Priklad 13.4.
Konstruktor FileInputStream(), kter² otevφrß soubor zadanΘho jmΘna (viz p°φklad 13.1.) neo╣et°uje p°φpad, ╛e soubor nenφ nalezen (nastane v²jimka FileNotFoundExeption) a p°enechßvß tuto starost volajφcφ metod∞. Ta m∙╛e nechat u╛ivatele zadat jmΘno souboru znovu, doplnit si jmΘno sama, skonΦit atd.

13.4. Propagace v²jimek

V²jimka m∙╛e b²t uvnit° metody vyvolßna dv∞ma zp∙soby:

  • p°φkazem throw (viz 13.2.),

  • volßnφm metody, kterß v²jimku deklaruje (viz 13.3.).

Pokud nenφ vyvolanß v²jimka zachycena blokem catch (viz str. 13) v metod∞, kde byla vyvolßna, je p°edßna o ·rove≥ v²╣ (volajφcφ metod∞). Takto se v²jimka rekurzivn∞ p°edßvß dokud nedojde k jejφmu zachycenφ a v krajnφm p°φpad∞ je zachycena runtime systΘmem, kter² zachycuje v╣echny v²jimky (standardn∞ vypφ╣e chybovou zprßvu a ukonΦφ program). Tento mechanismus se naz²vß propagace v²jimek.

Priklad 13.5.
public class Test {
   public static void main(String[] args) {
      try {
         a();                                        // (1)
      } catch(Exception e) {                         // (2)
         System.out.println("V²jimka zachycena.");
         e.printStackTrace();                        // (3)
      }
   }

   static void a() throws Exception {                // (*)
      b();                                           // (4)
   }

   static void b() throws Exception {                // (**)
      throw new Exception();                         // (5)
   }
}

Program zaΦφnß metodou main(), kde je volßna metoda a() (1), kterß nßsledn∞ volß metodu b() (4), v nφ╛ je vyvolßna v²jimka Exception (5). Tato v²jimka nenφ metodou b() zachycena a je proto propagovßna do volajφcφ metody a(). Zde rovn∞╛ nenφ zachycena a je dßle propagovßna do metody main(), kde je koneΦn∞ zachycena (2) a zp∙sobφ v²pis (3):

Vyjimka zachycena.
java.lang.Exception
        at Test.b(A.java:16)
        at Test.a(A.java:12)
        at Test.main(A.java:4)
Ob∞ metody, v nich╛ m∙╛e b²t v²jimka vyvolßna, ale nenφ zachycovßna, ji deklarujφ (*), (**).

13.5. Runtime v²jimky

Zvlß╣tnφ postavenφ mezi v²jimkami majφ tzv. runtime v²jimky - instance t°φdy RuntimeException a jejφch potomk∙. Tyto v²jimky nemusφ b²t v metodßch zachycovßny ani deklarovßny.

Runtime v²jimky toti╛ reprezentujφ chyby, kterΘ mohou nastat "kdekoliv" v programu. Jednß se nap°φklad o ArrayIndexOutOfBoundsException (p°eteΦenφ indexu pole) nebo ArithmeticException (aritmetickß chyba - celoΦφselnΘ d∞lenφ nulou) apod.

O╣et°ovßnφ t∞chto v²jimek by mnohdy znamenalo zbyteΦnou prßci navφc, nebo╗ nap°φklad ve for cyklu lze snadno zajistit, aby index pole meze nep°ekroΦil. Pokud by ArrayIndexOutOfBoundsException nebyla runtime v²jimkou, bylo by ji nutnΘ v ka╛dΘ metod∞, kterß pole pou╛φvß zachytit nebo deklarovat.

13.6. Koncov² blok (finally)

Dvojici blok∙ try - catch (viz str. 13) je mo╛nΘ roz╣φ°it o nepovinn² koncov² blok finally nßsledovn∞:

   try {
      // hlφdan² blok
   } catch( t°φdaV²jimek1 jmΘnoProm∞nnΘ1 ) {
      // o╣et°enφ v²jimky
   } finally {
      // zde uzav°en² k≤d se provede v╛dy
   }

Koncov²m blokem program pokraΦuje po ukonΦenφ hlφdanΘho i zßchytnΘho bloku (tj. a╗ u╛ v²jimka nastane nebo ne). Koncov² blok se vykonß dokonce i v p°φpad∞, ╛e:

  • je v try bloku vyvolßna v²jimka, kterou ╛ßdn² catch blok nezachycuje, nap°. runtime v²jimka (viz 13.5.) - a to je╣t∞ p°ed propagacφ tΘto v²jimky,

  • je v hlφdanΘm bloku vyvolßn p°φkaz return (viz 9.13.).


  • (1) Pro Φtenφ ze souboru pou╛ita je t°φda FileInputStream (viz kap. 15.) z balφku (viz kap. 12.) java.io. Ve stejnΘm balφku jsou definovßny i t°φdy v²jimek FileNotFoundException a IOException.
  • (2) P°i vyvolßnφ v²jimky v hlφdanΘm bloku se hledß prvnφ catch blok, kter² zachycuje odpovφdajφcφ t°φdu v²jimek.
  • (3) V²jimkou z toho pravidla jsou runtime v²jimky (viz 13.5.) a v²jimky t°φdy Error.

Predchozi
Converted by Selathco v0.9 on 25.09.1999 19:46
Dalsi