Programovanie

Výnimky v Jave, časť 1: Základné informácie o spracovaní výnimiek

Výnimkou Java sú typy knižníc a jazykové funkcie používané na zastupovanie a riešenie zlyhaní programu. Ak ste chceli pochopiť, ako je zlyhanie vyjadrené v zdrojovom kóde, ste na správnom mieste. Okrem prehľadu výnimiek jazyka Java vám pomôžeme s jazykovými funkciami jazyka Java na vyhadzovanie objektov, skúšanie kódu, ktorý môže zlyhať, chytanie vyhodených objektov a čistenie kódu Java po vyvolaní výnimky.

V prvej polovici tohto tutoriálu sa dozviete o základných jazykových vlastnostiach a typoch knižníc, ktoré existujú od verzie Java 1.0. V druhej polovici objavíte pokročilé funkcie zavedené v novších verziách Java.

Upozorňujeme, že príklady kódov v tomto tutoriále sú kompatibilné s JDK 12.

stiahnuť Získajte kód Stiahnite si zdrojový kód napríklad pre aplikácie v tejto príručke. Vytvoril Jeff Friesen pre JavaWorld.

Čo sú výnimky Java?

Zlyhanie nastane, keď je normálne správanie programu Java prerušené neočakávaným správaním. Táto odchýlka je známa ako výnimkou. Napríklad sa program pokúsi otvoriť súbor, aby prečítal jeho obsah, ale súbor neexistuje. Java klasifikuje výnimky do niekoľkých typov, zvážme teda každú z nich.

Skontrolované výnimky

Java klasifikuje výnimky vyplývajúce z externých faktorov (napríklad chýbajúci súbor) ako skontrolované výnimky. Kompilátor Java kontroluje, či sú tieto výnimky buď vybavil (opravené) tam, kde sa vyskytujú alebo je zdokumentované, že sa s nimi zaobchádza inde.

Obsluha výnimiek

An obsluha výnimky je sekvencia kódu, ktorá spracováva výnimku. Dotýka sa kontextu - to znamená, že číta hodnoty uložené z premenných, ktoré boli v rozsahu v čase, keď došlo k výnimke - a potom použije to, čo sa naučí, na obnovenie behu programu Java. Obslužný program výnimiek môže napríklad prečítať uložený názov súboru a vyzvať používateľa, aby nahradil chýbajúci súbor.

Výnimky za behu (neoznačené)

Predpokladajme, že sa program pokúsi rozdeliť celé číslo na celé číslo 0. Táto nemožnosť ilustruje iný druh výnimky, a to a runtime výnimka. Na rozdiel od kontrolovaných výnimiek, runtime výnimky zvyčajne vychádzajú zo zle napísaného zdrojového kódu, a mal by ich preto opraviť programátor. Pretože kompilátor nekontroluje, či sú runtime výnimky spracované alebo zdokumentované tak, aby boli spracované inde, môžete si runtime výnimku predstaviť ako nekontrolovaná výnimka.

O výnimkách za behu

Program môžete upraviť tak, aby spracovával výnimku za behu, ale je lepšie opraviť zdrojový kód. Výnimky za behu často vznikajú pri odovzdávaní neplatných argumentov metódam knižnice; buggy volací kód by mal byť opravený.

Chyby

Niektoré výnimky sú veľmi vážne, pretože ohrozujú schopnosť programu pokračovať v jeho spustení. Napríklad program sa pokúša prideliť pamäť z JVM, ale nie je dostatok voľnej pamäte na uspokojenie požiadavky. Ďalšia vážna situácia nastane, keď sa program pokúsi načítať triedny súbor pomocou a Class.forName () volanie metódy, ale triedny súbor je poškodený. Tento druh výnimky je známy ako chyba. Nikdy by ste sa nemali pokúšať chyby spracovávať sami, pretože JVM sa z nich nemusí vedieť spamätať.

Výnimky v zdrojovom kóde

Výnimku možno v zdrojovom kóde predstavovať ako kód chyby alebo ako objekt. Predstavím oboje a ukážem vám, prečo sú predmety lepšie.

Chybové kódy verzus objekty

Programovacie jazyky ako C používajú celočíselné chybové kódy predstavovať zlyhanie a dôvody zlyhania - teda výnimky. Tu je niekoľko príkladov:

if (chdir ("C: \ temp")) printf ("Nemožno zmeniť dočasný adresár:% d \ n", errno); SÚBOR * fp = fopen ("C: \ temp \ foo"); if (fp == NULL) printf ("Nie je možné otvoriť foo:% d \ n", errno);

C chdir () (zmena adresára) funkcia vráti celé číslo: 0 pri úspechu alebo -1 pri zlyhaní. Podobne aj C fopen () (otvorený súbor) vráti nenulovú hodnotu ukazovateľ (celočíselná adresa) na a SÚBOR štruktúra na úspech alebo nulový (0) ukazovateľ (predstavovaný konštantou NULOVÝ) pri zlyhaní. V obidvoch prípadoch si musíte prečítať globálnu, aby ste identifikovali výnimku, ktorá zlyhanie spôsobila errno celočíselný chybový kód premennej.

Chybové kódy spôsobujú určité problémy:

  • Celé čísla sú nezmyselné; neopisujú výnimky, ktoré zastupujú. Čo napríklad znamená 6?
  • Priraďovanie kontextu k chybovému kódu je nepríjemné. Napríklad budete chcieť vytlačiť názov súboru, ktorý sa nepodarilo otvoriť, ale kam chcete uložiť názov súboru?
  • Celé čísla sú ľubovoľné, čo môže pri čítaní zdrojového kódu viesť k zámene. Napríklad upresnenie if (! chdir ("C: \ temp")) (! znamená NIE) namiesto if (chdir ("C: \ temp")) testovanie zlyhania je jasnejšie. Avšak 0 bola vybraná na označenie úspechu atď if (chdir ("C: \ temp")) musí byť špecifikované na testovanie poruchy.
  • Chybové kódy je príliš ľahké ignorovať, čo môže viesť k chybovému kódu. Môže napríklad určiť programátor chdir ("C: \ temp"); a ignorovať if (fp == NULL) skontrolovať. Ďalej nemusí programátor skúmať errno. Testovaním chyby sa program chová nestabilne, keď niektorá z funkcií vráti indikátor zlyhania.

Na vyriešenie týchto problémov Java prijala nový prístup k spracovaniu výnimiek. V Jave kombinujeme objekty, ktoré popisujú výnimky, s mechanizmom založeným na hádzaní a chytaní týchto objektov. Tu sú niektoré výhody použitia objektov oproti chybovému kódu na označenie výnimiek:

  • Objekt je možné vytvoriť z triedy so zmysluplným názvom. Napríklad, FileNotFoundException (v java.io balíček) je zmysluplnejšia ako 6.
  • Objekty môžu ukladať kontext do rôznych polí. Do polí objektu môžete napríklad uložiť správu, názov súboru, ktorý sa nedal otvoriť, najnovšiu pozíciu, kde zlyhala operácia syntaktickej analýzy, alebo ďalšie položky.
  • Nepoužívate ak vyhlásenia na testovanie zlyhania. Namiesto toho sa objekty výnimky vrhnú na obslužnú rutinu, ktorá je oddelená od programového kódu. Vďaka tomu je zdrojový kód ľahšie čitateľný a je menej pravdepodobné, že bude chybný.

Hádzateľná a jej podtriedy

Java poskytuje hierarchiu tried, ktoré predstavujú rôzne druhy výnimiek. Tieto triedy majú korene v java.lang balíček Hoditeľné triedy, spolu s jej Výnimka, RuntimeExceptiona Chyba podtriedy.

Hoditeľné je najvyššia nadtrieda, pokiaľ ide o výnimky. Iba objekty vytvorené z Hoditeľné a jeho podtriedy môžu byť vyhodené (a následne chytené). Takéto objekty sú známe ako hádzacie predmety.

A Hoditeľné objekt je spojený s a podrobná správa ktorý popisuje výnimku. Na vytvorenie a. Je poskytnutých niekoľko konštruktorov, vrátane dvojice popísanej nižšie Hoditeľné objekt s podrobnou správou alebo bez nej:

  • Hádzateľné () vytvára a Hoditeľné bez podrobnej správy. Tento konštruktor je vhodný pre situácie, kde nie je žiadny kontext. Napríklad by ste chceli vedieť iba to, že zásobník je prázdny alebo plný.
  • Hádzateľné (reťazcová správa) vytvára a Hoditeľné s správa ako podrobná správa. Túto správu je možné odoslať používateľovi alebo prihlásiť.

Hoditeľné poskytuje Reťazec getMessage () spôsob vrátenia podrobnej správy. Poskytuje tiež ďalšie užitočné metódy, ktoré uvediem neskôr.

Trieda Výnimka

Hoditeľné má dve priame podtriedy. Jedna z týchto podtried je Výnimka, ktorý popisuje výnimku spôsobenú externým faktorom (napríklad pokusom o čítanie z neexistujúceho súboru). Výnimka deklaruje rovnaké konštruktory (s rovnakými zoznamami parametrov) ako Hoditeľné, a každý konštruktor sa dovolá svojho Hoditeľné náprotivok. Výnimka dedí Hoditeľnémetódy; nedeklaruje žiadne nové metódy.

Java poskytuje mnoho tried výnimiek, ktoré priamo podtriedy Výnimka. Tu sú tri príklady:

  • CloneNotSupportedException signalizuje pokus o klonovanie objektu, ktorého trieda neimplementuje Cloneable rozhranie. Oba typy sú v java.lang balíček.
  • Výnimka IO signalizuje, že došlo k nejakému zlyhaniu I / O. Tento typ sa nachádza v java.io balíček.
  • Výnimka signalizuje, že pri analýze textu došlo k zlyhaniu. Tento typ nájdete v java.text balíček.

Všimnite si, že každý Výnimka názov podtriedy končí slovom Výnimka. Táto konvencia uľahčuje identifikáciu účelu triedy.

Spravidla budete podtriedou Výnimka (alebo jedna z jeho podtried) s vašimi vlastnými triedami výnimiek (ktorých názvy by sa mali končiť na Výnimka). Tu je niekoľko príkladov vlastných podtried:

public class StackFullException extends Exception {} public class EmptyDirectoryException extends Exception {private String directoryName; public EmptyDirectoryException (String message, String directoryName) {super (správa); this.directoryName = adresár; } public String getDirectoryName () {návrat adresáraName; }}

Prvý príklad popisuje triedu výnimiek, ktorá nevyžaduje podrobnú správu. Je to predvolené vyvolanie konštruktora noargument Výnimka (), ktorý sa dovoláva Hádzateľné ().

Druhý príklad popisuje triedu výnimiek, ktorej konštruktor vyžaduje podrobnú správu a názov prázdneho adresára. Konštruktor vyvolá Výnimka (reťazcová správa), ktorý sa dovoláva Hádzateľné (reťazcová správa).

Objekty inštancované z Výnimka alebo jedna z jeho podtried (okrem RuntimeException alebo jedna z jeho podtried) sú kontrolované výnimky.

Trieda RuntimeException

Výnimka je priamo podtriedený RuntimeException, ktorý popisuje výnimku, ktorá najpravdepodobnejšie vyplýva zo zle napísaného kódu. RuntimeException deklaruje rovnaké konštruktory (s rovnakými zoznamami parametrov) ako Výnimka, a každý konštruktor sa dovolá svojho Výnimka náprotivok. RuntimeException dedí Hoditeľnémetódy. Deklaruje žiadne nové metódy.

Java poskytuje mnoho tried výnimiek, ktoré priamo podtriedy RuntimeException. Nasledujúce príklady sú všetci členmi java.lang balenie:

  • Aritmetická výnimka signalizuje neplatnú aritmetickú operáciu, napríklad pokus o vydelenie celého čísla číslom 0.
  • IllegalArgumentException signalizuje, že metóde bol predložený nezákonný alebo nevhodný argument.
  • NullPointerException signalizuje pokus o vyvolanie metódy alebo prístup k poľu inštancie prostredníctvom nulovej referencie.

Objekty inštancované z RuntimeException alebo jedna z jeho podtried je nekontrolované výnimky.

Trieda Chyba

HoditeľnéĎalšia priama podtrieda je Chyba, ktorý popisuje závažný (aj nenormálny) problém, s ktorým by sa rozumná aplikácia nemala pokúšať vyrovnať - napríklad nedostatok pamäte, pretečenie zásobníka JVM alebo pokus o načítanie triedy, ktorú nemožno nájsť. Páči sa mi to Výnimka, Chyba deklaruje rovnaké konštruktory ako Hoditeľné, dedí Hoditeľnémetódy a nedeklaruje žiadnu zo svojich metód.

Môžete identifikovať Chyba podtriedy z konvencie, ktorou sa názvy ich tried končia Chyba. Príklady zahŕňajú OutOfMemoryError, Chyba prepojeniaa StackOverflowError. Všetky tri typy patria do skupiny java.lang balíček.

Hádzanie výnimiek

Funkcia knižnice C upozorňuje na volací kód výnimky nastavením globálnej hodnoty errno premenná na chybový kód a vrátenie chybového kódu. Naopak, metóda Java hodí objekt. Vedieť, ako a kedy hodiť výnimky, je základným aspektom efektívneho programovania v jazyku Java. Vyhodenie výnimky zahŕňa dva základné kroky:

  1. Použi hodiť vyhlásenie hodiť objekt výnimky.
  2. Použi hodí doložka informovať kompilátora.

Neskôr sa časti zameriavajú na chytanie výnimiek a čistenie po nich, najskôr sa však dozvieme viac o hádzacích veciach.

Vyhlásenie hodu

Java poskytuje hodiť príkaz hodiť objekt, ktorý popisuje výnimku. Tu je syntax súboru hodiť vyhlásenie:

hodiť hádzateľná;

Objekt identifikovaný podľa hádzateľná je príkladom Hoditeľné alebo ktorákoľvek z jeho podtried. Zvyčajne však hádžete iba objekty inštancované z podtriedy Výnimka alebo RuntimeException. Tu je niekoľko príkladov:

hodiť novú FileNotFoundException ("nemôžem nájsť súbor" + názov súboru); throw new IllegalArgumentException ("argument odovzdaný do počtu je menší ako nula");

Vrhací prostriedok je vyhodený z aktuálnej metódy na JVM, ktorý skontroluje vhodnosť tejto metódy pre túto metódu. Ak sa nenájde, JVM odvinie zásobník volaní metód a hľadá najbližšiu metódu volania, ktorá dokáže spracovať výnimku opísanú v hode. Ak nájde túto metódu, odovzdá vrhaciu metódu handlerovi metódy, ktorého kód sa vykoná na spracovanie výnimky. Ak sa nenájde žiadna metóda na spracovanie výnimky, JVM sa ukončí vhodnou správou.

Doložka o hodoch

Musíte vyhodiť kompilátor, keď vyhodíte z metódy kontrolovanú výnimku. Urobte to pripojením a hodí doložka k hlavičke metódy. Táto doložka má nasledujúcu syntax:

hodí checkedExceptionClassName (, checkedExceptionClassName)*

A hodí doložka sa skladá z kľúčového slova hodí nasledovaný čiarkami oddeleným zoznamom názvov tried kontrolovaných výnimiek vyhodených z metódy. Tu je príklad:

public static void main (String [] args) hodí ClassNotFoundException {if (args.length! = 1) {System.err.println ("usage: java ... classfile"); návrat; } Class.forName (args [0]); }

Tento príklad sa pokúša načítať súbor triedy identifikovaný argumentom príkazového riadku. Ak Class.forName () nemôže nájsť triedny súbor, hodí a java.lang.ClassNotFoundException objekt, čo je kontrolovaná výnimka.

Overená kontroverzia výnimiek

The hodí doložka a kontrolované výnimky sú kontroverzné. Mnoho vývojárov nenávidí, keď sú nútení špecifikovať hodí alebo spracovať zaškrtnuté výnimky. Viac informácií sa dozviete z môjho článku Sú zaškrtnuté výnimky dobré alebo zlé? príspevok v blogu.

$config[zx-auto] not found$config[zx-overlay] not found