Vodič kroz Java na kraju Ključna riječ

1. Pregled

U ovom uputstvu istražit ćemo konačno ključna riječ u Javi. Vidjet ćemo kako ćemo je upotrijebiti pokušaj uhvatiti blokovi u rukovanju pogreškama. Iako konačno namijenjen je zajamčenju izvršenja koda, razgovarat ćemo o iznimnim situacijama u kojima ga JVM ne izvršava.

Također ćemo razgovarati o nekim uobičajenim zamkama gdje a konačno blok može imati neočekivani ishod.

2. Što je konačno?

konačno definira blok koda koji koristimo zajedno s probati ključna riječ. Definira kod koji se uvijek izvodi nakon probati i bilo koji ulov blok, prije nego što je metoda dovršena.

The konačno blok se izvršava bez obzira je li izuzetak bačen ili uhvaćen.

2.1. Brzi primjer

Pogledajmo konačno u probaj-uhvati-napokon blok:

isprobajte {System.out.println ("Brojanje je" + Integer.parseInt (count)); } catch (NumberFormatException e) {System.out.println ("No count"); } napokon {System.out.println ("Napokon u"); } 

U ovom primjeru, bez obzira na vrijednost parametra računati, JVM izvršava konačno blok i otisci "Napokon".

2.2. Koristeći konačno Bez a ulov Blok

Također, možemo koristiti a konačno blok s probati blok bez obzira je li a ulov blok je prisutan:

probajte {System.out.println ("Inside try"); } napokon {System.out.println ("Napokon konačno"); }

I dobit ćemo izlaz:

Pokušajte iznutra napokon

2.3. Zašto konačno Je korisno

Općenito koristimo konačno blok za izvršavanje koda za čišćenje, poput zatvaranja veza, zatvaranja datoteka ili oslobađanja niti, jer se izvršava bez obzira na iznimku.

Bilješka: try-with-resources se također može koristiti za zatvaranje resursa umjesto a konačno blok.

3. Kada konačno Je li izvršen

Pogledajmo sve permutacije kada se JVM izvršava konačno blokova, tako da to možemo bolje razumjeti.

3.1. Nije izuzetak izbačen

Kada probati blok dovršava, konačno blok se izvršava, čak i ako nije bilo iznimke:

probajte {System.out.println ("Inside try"); } napokon {System.out.println ("Napokon iznutra"); }

U ovom primjeru ne donosimo iznimku od probati blok. Dakle, JVM izvršava sav kôd u oba probati i konačno blokovi.

Ovo daje:

Pokušajte iznutra napokon

3.2. Iznimka se baca i ne rješava se

Ako postoji iznimka i ona nije uhvaćena, konačno blok se i dalje izvršava:

probajte {System.out.println ("Inside try"); baciti novi Exception (); } napokon {System.out.println ("Napokon iznutra"); }

JVM izvršava konačno blok čak i u slučaju neobrađene iznimke.

A izlaz bi bio:

Pokušajte iznutra Napokon izuzetak u niti "main" java.lang.Exception

3.3. Iznimka se baca i njome se rukuje

Ako postoji iznimka i uhvati je ulov blok, konačno blok se i dalje izvršava:

probajte {System.out.println ("Inside try"); baciti novi Exception (); } catch (Iznimka e) {System.out.println ("Inside catch"); } napokon {System.out.println ("Napokon iznutra"); }

U ovom slučaju, ulov blok obrađuje bačenu iznimku, a zatim JVM izvršava konačno blok i proizvodi izlaz:

Unutra probajte Unutra napokon uhvatite Unutra

3.4. Metoda se vraća iz probati Blok

Čak i povratak s metode neće spriječiti konačno blokovi iz trčanja:

probajte {System.out.println ("Inside try"); povratak "iz pokušaja"; } napokon {System.out.println ("Napokon iznutra"); }

Ovdje, iako metoda ima a povratak izjava, JVM izvršava konačno blok prije predaje kontrole pozivajućoj metodi.

Dobit ćemo izlaz:

Pokušajte iznutra napokon

3.5. Metoda se vraća iz ulov Blok

Kada ulov blok sadrži a povratak izjava, konačno blok se i dalje zove:

probajte {System.out.println ("Inside try"); baciti novi Exception (); } catch (Iznimka e) {System.out.println ("Inside catch"); povratak "iz ulova"; } napokon {System.out.println ("Napokon konačno"); }

Kada bacimo iznimku iz probati blok, ulov blok obrađuje iznimku. Iako postoji povratna izjava u ulov blok, JVM izvršava konačno blok prije predaje kontrole pozivajućoj metodi i on daje:

Unutra probajte Unutra napokon uhvatite Unutra

4. Kada konačno Nije izvršeno

Iako uvijek očekujemo da JVM izvrši izjave unutar a konačno blok, postoje neke situacije u kojima JVM neće izvršiti a konačno blok.

Već bismo mogli očekivati ​​da ako operativni sustav zaustavi naš program, program neće dobiti priliku izvršiti sav svoj kôd. Također možemo poduzeti neke radnje koje će na sličan način spriječiti izvršenje čekajućeg postupka konačno blok.

4.1. Pozivanje System.exit

U ovom slučaju završavamo JVM pozivom System.exit i stoga JVM neće izvršiti naše konačno blok:

probajte {System.out.println ("Inside try"); System.exit (1); } napokon {System.out.println ("Napokon konačno"); }

Ovo daje:

Pokušajte iznutra

4.2. Pozivanje zaustaviti

Slično System.exit, poziv na Runtime.halt također zaustavlja izvršenje i JVM ne izvršava nijedno konačno blokovi:

probajte {System.out.println ("Inside try"); Runtime.getRuntime (). Halt (1); } napokon {System.out.println ("Napokon konačno"); }

Dakle, izlaz će biti:

Pokušajte iznutra

4.3. Daemon Thread

Ako Daemon nit uđe u izvršavanje a probaj / napokon blok i sve ostale ne-daemon niti izlaze prije nego što daemon nit izvrši konačno blok, JVM ne čeka da daemon nit završi izvršenje konačno blok:

Izvodljivo runnable = () -> {try {System.out.println ("Inside try"); } napokon {try {Thread.sleep (1000); System.out.println ("Napokon unutra"); } catch (InterruptedException e) {e.printStackTrace (); }}}; Tema redovita = nova nit (koja se može izvoditi); Daemon niti = nova nit (koja se može pokrenuti); daemon.setDaemon (true); regular.start (); Navoj.spavanje (300); daemon.start ();

U ovom primjeru, izvodljiv otisci "Unutarnji pokušaj" čim uđe u metodu i pričeka 1 sekundu prije ispisa "Napokon unutra".

Evo, započinjemo redovito nit i demon konac s malim zakašnjenjem. Kada redovito nit izvršava konačno blok, demon nit još uvijek čeka unutar probati blok. Kao redovito nit dovršava izvršenje i izlazi, JVM također izlazi i ne čeka demon nit za dovršetak konačno blok.

Evo rezultata:

Pokušajte iznutra Pokušajte iznutra Napokon napokon

4.4. JVM doseže beskonačnu petlju

Evo a probati blok koji sadrži beskonačno dok petlja:

probajte {System.out.println ("Inside try"); while (true) {}} napokon {System.out.println ("Unutra konačno"); }

Iako to nije specifično za konačno, vrijedi spomenuti da ako probati ili ulov blok sadrži beskonačnu petlju, JVM nikada neće doći do bilo kojeg bloka izvan te petlje.

5. Uobičajene zamke

Postoje neke uobičajene zamke koje moramo izbjegavati kada koristimo konačno blok.

Iako je potpuno legalno, smatra se lošom praksom imati povratak izjava ili izuzetak iz a konačno blok, i trebali bismo ga izbjeći pod svaku cijenu.

5.1. Zanemaruje iznimku

A povratak izjava u konačno blok ignorira neuhvaćenu iznimku:

probajte {System.out.println ("Inside try"); baciti novi RuntimeException (); } napokon {System.out.println ("Napokon konačno"); povratak "iz napokon"; }

U ovom slučaju, metoda zanemaruje RuntimeException bačena i vraća vrijednost "Od napokon".

5.2. Zanemaruje ostalo povratak Izjave

A povratak izjava u konačno blok ignorira bilo koji drugi povratni izraz u probati ili ulov blok. Samo povratak izjava u konačno blok izvršava:

probajte {System.out.println ("Inside try"); povratak "iz pokušaja"; } napokon {System.out.println ("Napokon konačno"); povratak "iz napokon"; }

U ovom se primjeru metoda uvijek vraća "Od napokon" i potpuno ignorira povratak izjava u probati blok. Ovo bi mogla biti vrlo teška pogreška, zbog čega bismo trebali izbjegavati upotrebu povratak u konačno blokovi.

5.3. Mijenja ono što je bačeno ili vraćeno

Također, u slučaju izbacivanja iznimke iz a konačno blok, metoda zanemaruje izuzetak bačen ili povratak izjave u probati i ulov blokovi:

probajte {System.out.println ("Inside try"); povratak "iz pokušaja"; } napokon {baciti novi RuntimeException (); }

Ova metoda nikad ne vraća vrijednost i uvijek baca a RuntimeException.

Iako možda nećemo namjerno izuzeti iznimku od konačno blok kao u ovom primjeru, još uvijek možemo naići na ovaj problem. Može se dogoditi kada metode čišćenja koje koristimo u a konačno blok baciti iznimku.

6. Zaključak

U ovom smo članku razgovarali o čemu konačno blokovi rade u Javi i kako ih koristiti. Zatim smo pregledali različite slučajeve kada ih JVM izvršava, a nekoliko i kad ih možda nije.

Na kraju smo pogledali neke uobičajene zamke povezane s korištenjem konačno blokovi.

Kao i uvijek, izvorni kod korišten u ovom vodiču dostupan je na GitHub-u.