Sprievodca kľúčovým slovom Java konečne

1. Prehľad

V tomto výučbe sa pozrieme na konečne kľúčové slovo v Jave. Uvidíme, ako to popri tom využijeme Skús chytiť bloky pri spracovaní chýb. Predsa konečne má zaručiť vykonávanie kódu, budeme diskutovať o výnimočných situáciách, v ktorých ho JVM nevykoná.

Rozoberieme tiež niektoré bežné úskalia, kde a konečne blok môže mať neočakávaný výsledok.

2. Čo je konečne?

konečne definuje blok kódu, ktorý používame spolu s skús kľúčové slovo. Definuje kód, ktorý sa vždy spustí po skús a hocijaké chytiť pred dokončením metódy.

The konečne blok sa vykoná bez ohľadu na to, či je vyvolaná alebo chytená výnimka.

2.1. Rýchly príklad

Poďme sa pozrieť na konečne v skús chytiť-konečne blok:

try {System.out.println ("Počet je" + Integer.parseInt (počet)); } catch (NumberFormatException e) {System.out.println ("Bez počtu"); } konečne {System.out.println ("V konečne"); } 

V tomto príklade bez ohľadu na hodnotu parametra počítať, JVM vykonáva konečne blokovať a tlačiť "Konečne".

2.2. Použitím konečne Bez a chytiť Blokovať

Tiež môžeme použiť a konečne blok s a skús blok bez ohľadu na to, či a chytiť blok je prítomný:

try {System.out.println ("Inside try"); } konečne {System.out.println ("Konečne vnútri"); }

A dostaneme výstup:

Vnútri skúste konečne Vnútri

2.3. Prečo konečne Je užitočné

Spravidla používame konečne blok na vykonanie vyčistenia kódu, ako je ukončenie pripojení, zatvorenie súborov alebo uvoľnenie vlákien, pretože sa vykonáva bez ohľadu na výnimku.

Poznámka: try-with-resources možno použiť aj na zatvorenie zdrojov namiesto a konečne blokovať.

3. Kedy konečne Je popravený

Pozrime sa na všetky permutácie, keď sa vykoná JVM konečne bloky, aby sme tomu lepšie rozumeli.

3.1. Nie je hodená žiadna výnimka

Keď skús blok dokončí, konečne blok sa vykoná, aj keď neexistovala žiadna výnimka:

try {System.out.println ("Inside try"); } konečne {System.out.println ("Konečne vnútri"); }

V tomto príklade nehádžeme výnimku z skús blokovať. Preto JVM vykoná všetok kód v oboch skús a konečne blokov.

Tento výstup:

Vnútri skúste konečne Vnútri

3.2. Výnimka je vyhodená a nespracováva sa

Ak existuje výnimka a tá sa nechytí, konečne blok je stále vykonaný:

try {System.out.println ("Inside try"); hodiť novú Výnimku (); } konečne {System.out.println ("Konečne vnútri"); }

JVM vykonáva konečne blok aj v prípade nespracovanej výnimky.

A výstup by bol:

Inside skúste Inside konečne Výnimka vo vlákne "main" java.lang.Exception

3.3. Je vyhodená výnimka a je s ňou manipulované

Ak existuje výnimka a chytí ju chytiť blok, konečne blok je stále vykonaný:

try {System.out.println ("Inside try"); hodiť novú Výnimku (); } catch (Výnimka e) {System.out.println ("Inside catch"); } konečne {System.out.println ("Konečne vnútri"); }

V takom prípade chytiť blok spracuje vyhodenú výnimku a potom JVM vykoná konečne blok a vyprodukuje výstup:

Vnútri skúste Inside chytiť Inside konečne

3.4. Metóda sa vracia z skús Blokovať

Ani návrat z metódy nezabráni konečne spustené bloky:

try {System.out.println ("Inside try"); návrat „z pokusu“; } konečne {System.out.println ("Konečne vnútri"); }

Tu, aj keď má metóda a návrat vyhlásenie, JVM vykoná konečne blok pred odovzdaním kontroly volacej metóde.

Dostaneme výstup:

Vnútri skúste konečne Vnútri

3.5. Metóda sa vracia z chytiť Blokovať

Keď chytiť blok obsahuje a návrat vyhlásenie, konečne blok sa stále volá:

try {System.out.println ("Inside try"); hodiť novú Výnimku (); } catch (Výnimka e) {System.out.println ("Inside catch"); návrat „z úlovku“; } konečne {System.out.println ("Konečne vnútri"); }

Keď hodíme výnimku z skús blok, chytiť blok spracuje výnimku. Aj keď v chytiť blok, JVM vykoná konečne blokuje pred odovzdaním kontroly volajúcej metóde a na výstupe je:

Vnútri skúste Inside chytiť Inside konečne

4. Kedy konečne Nie je popravený

Aj keď vždy očakávame, že JVM vykoná príkazy vnútri a konečne bloku, existujú niektoré situácie, keď JVM nevykoná a konečne blokovať.

Už by sme mohli očakávať, že ak operačný systém zastaví náš program, potom by program nemal šancu spustiť všetok svoj kód. Existujú aj niektoré kroky, ktoré môžeme podniknúť a ktoré podobne zabránia vykonaniu nespracovaného produktu konečne blokovať.

4.1. Vyvolávanie System.exit

V takom prípade ukončujeme JVM volaním System.exit a teda JVM nebude vykonávať našu konečne blok:

try {System.out.println ("Inside try"); System.exit (1); } konečne {System.out.println ("Konečne vnútri"); }

Tento výstup:

Vo vnútri vyskúšajte

4.2. Vyvolávanie zastaviť

Podobný System.exit, hovor na Runtime.halt tiež zastaví exekúciu a JVM nevykoná žiadnu konečne bloky:

try {System.out.println ("Inside try"); Runtime.getRuntime (). Halt (1); } konečne {System.out.println ("Konečne vnútri"); }

Výstupom teda bude:

Vyskúšajte vo vnútri

4.3. Daemon Thread

Ak vlákno Daemon vstúpi do vykonania a skús / konečne blok a všetky ostatné vlákna, ktoré nie sú démonmi, sa ukončia skôr, ako vlákno démona vykoná súbor konečne blok, JVM nečaká, kým vlákno démona dokončí vykonávanie konečne blok:

Runnable runnable = () -> {try {System.out.println ("Inside try"); } konečne {skús {Thread.sleep (1000); System.out.println ("Konečne vnútri"); } catch (InterruptedException e) {e.printStackTrace (); }}}; Vlákno bežné = nové vlákno (spustiteľné); Démon vlákna = nové vlákno (spustiteľné); daemon.setDaemon (true); regular.start (); Závit. Spánok (300); daemon.start ();

V tomto príklade spustiteľný výtlačky „Inside try“ hneď ako vstúpi do metódy a pred tlačou počká 1 sekundu "Konečne dovnútra".

Tu začíname pravidelné závit a démon vlákno s malým oneskorením. Keď pravidelné vlákno vykoná konečne blok, démon vlákno stále čaká v rámci skús blokovať. Ako pravidelné vlákno dokončí vykonanie a ukončí sa, JVM sa tiež ukončí a nečaká na démon vlákno na dokončenie konečne blokovať.

Tu je výstup:

Inside try Inside try inside Inside konečne

4.4. JVM dosahuje nekonečnú slučku

Tu je skús blok, ktorý obsahuje nekonečno zatiaľ čo slučka:

try {System.out.println ("Inside try"); while (true) {}} konečne {System.out.println ("Inside konečne"); }

Aj keď to nie je konkrétne konečne, stojí za zmienku, že ak skús alebo chytiť blok obsahuje nekonečnú slučku, JVM nikdy nedosiahne žiadny blok mimo túto slučku.

5. Časté úskalia

Existujú niektoré bežné úskalia, ktorým sa musíme pri používaní konečne blokovať.

Aj keď je to úplne legálne, považuje sa za zlý postup mať návrat vyhlásenie alebo hod výnimku z a konečne blok, a mali by sme sa mu za každú cenu vyhnúť.

5.1. Ignoruje výnimku

A návrat vyhlásenie v konečne blok ignoruje nezachytenú výnimku:

try {System.out.println ("Inside try"); hodiť nový RuntimeException (); } konečne {System.out.println ("Konečne vnútri"); návrat „z konečne“; }

V takom prípade metóda ignoruje RuntimeException vyhodený a vráti hodnotu „Konečne“.

5.2. Ignoruje iné návrat Vyhlásenia

A návrat vyhlásenie v konečne blok ignoruje akýkoľvek iný návratový príkaz v priečinku skús alebo chytiť blokovať. Len návrat vyhlásenie v konečne blok vykoná:

try {System.out.println ("Inside try"); návrat „z pokusu“; } konečne {System.out.println ("Konečne vnútri"); návrat „z konečne“; }

V tomto príklade sa metóda vždy vráti „Konečne“ a úplne ignoruje návrat vyhlásenie v skús blokovať. Toto by mohla byť veľmi ťažko zistiteľná chyba, a preto by sme sa mali vyhnúť použitiu návrat v konečne blokov.

5.3. Zmení to, čo je vyhodené alebo vrátené

Taktiež v prípade hodenia výnimky z a konečne blok, metóda ignoruje vyvolanú výnimku alebo návrat vyhlásenia v skús a chytiť bloky:

try {System.out.println ("Inside try"); návrat „z pokusu“; } konečne {hodiť novú RuntimeException (); }

Táto metóda nikdy nevráti hodnotu a vždy hodí a RuntimeException.

Aj keď zámerne nemôžeme vylúčiť výnimku z konečne blok ako v tomto príklade, s týmto problémom sa môžeme ešte stretnúť. Môže sa to vyskytnúť, keď metódy čistenia, ktoré používame v a konečne blok hodiť výnimku.

6. Záver

V tomto článku sme diskutovali o tom, čo konečne bloky robia v Jave a ako ich používa. Potom sme sa pozreli na rôzne prípady, keď ich JVM vykoná, a na niekoľko prípadov, keď to tak nemusí byť.

Na záver sme sa pozreli na niektoré bežné úskalia spojené s používaním konečne blokov.

Ako vždy, zdrojový kód použitý v tomto tutoriále je k dispozícii na GitHub.