Gids voor het Java eindelijk sleutelwoord

1. Overzicht

In deze zelfstudie verkennen we de Tenslotte trefwoord in Java. We zullen zien hoe je het ernaast kunt gebruiken proberen te vangen blokkeert foutafhandeling. Alhoewel Tenslotte is bedoeld om de uitvoering van code te garanderen, bespreken we uitzonderlijke situaties waarin de JVM deze niet uitvoert.

We bespreken ook enkele veelvoorkomende valkuilen waarbij a Tenslotte blok kan een onverwachte uitkomst hebben.

2. Wat is Tenslotte?

Tenslotte definieert een codeblok dat we gebruiken samen met de proberen trefwoord. Het definieert code die altijd wordt uitgevoerd na de proberen En elk vangst block, voordat de methode is voltooid.

De Tenslotte block wordt uitgevoerd ongeacht of er een uitzondering wordt gegenereerd of opgevangen.

2.1. Een snel voorbeeld

Laten we eens kijken Tenslotte in een probeer-vangst-eindelijk blok:

probeer {System.out.println ("The count is" + Integer.parseInt (count)); } catch (NumberFormatException e) {System.out.println ("Geen telling"); } eindelijk {System.out.println ("In eindelijk"); } 

In dit voorbeeld, ongeacht de waarde van de parameter tellenvoert de JVM het Tenslotte blok en afdrukken "In eindelijk".

2.2. Gebruik makend van Tenslotte Zonder een vangst Blok

We kunnen ook gebruiken een Tenslotte blok met een proberen blokkeren, ongeacht of een vangst blok is aanwezig:

probeer {System.out.println ("Inside try"); } eindelijk {System.out.println ("Inside eindelijk"); }

En we krijgen de output:

Binnen, probeer het dan eindelijk eens

2.3. Waarom Tenslotte Is nuttig

We gebruiken over het algemeen de Tenslotte block om opschoningscode uit te voeren, zoals het sluiten van verbindingen, het sluiten van bestanden of het vrijmaken van threads, aangezien het wordt uitgevoerd ongeacht een uitzondering.

Opmerking: try-with-resources kan ook worden gebruikt om resources te sluiten in plaats van een Tenslotte blok.

3. Wanneer Tenslotte Is geëxecuteerd

Laten we eens kijken naar alle permutaties van wanneer de JVM wordt uitgevoerd Tenslotte blokken, zodat we het beter kunnen begrijpen.

3.1. Er wordt geen uitzondering gemaakt

Wanneer de proberen blok is voltooid, het Tenslotte blok wordt uitgevoerd, zelfs als er geen uitzondering was:

probeer {System.out.println ("Inside try"); } eindelijk {System.out.println ("Inside eindelijk"); }

In dit voorbeeld gooien we geen uitzondering van de proberen blok. De JVM voert dus alle code uit in zowel het proberen en Tenslotte blokken.

Dit levert:

Binnen, probeer het dan eindelijk eens

3.2. Uitzondering wordt geworpen en niet afgehandeld

Als er een uitzondering is en deze niet wordt opgevangen, wordt de Tenslotte blok wordt nog steeds uitgevoerd:

probeer {System.out.println ("Inside try"); gooi nieuwe uitzondering (); } eindelijk {System.out.println ("Inside eindelijk"); }

De JVM voert het Tenslotte blokkeren, zelfs in het geval van een niet-verwerkte uitzondering.

En de output zou zijn:

Binnen probeer Inside eindelijk Uitzondering in thread "main" java.lang.Exception

3.3. Uitzondering wordt geworpen en afgehandeld

Als er een uitzondering is en deze wordt opgevangen door de vangst block, het Tenslotte blok wordt nog steeds uitgevoerd:

probeer {System.out.println ("Inside try"); gooi nieuwe uitzondering (); } catch (uitzondering e) {System.out.println ("Inside catch"); } eindelijk {System.out.println ("Inside eindelijk"); }

In dit geval is het vangst block handelt de gegenereerde uitzondering af en vervolgens voert de JVM de Tenslotte block en produceert de output:

Probeer binnenin eindelijk binnen te vangen

3.4. Methode Keert terug van proberen Blok

Zelfs het terugkeren van de methode zal niet voorkomen Tenslotte blokken tegen hardlopen:

probeer {System.out.println ("Inside try"); terugkeer "van proberen"; } eindelijk {System.out.println ("Inside eindelijk"); }

Hier, ook al heeft de methode een terugkeer statement, voert de JVM de Tenslotte block voordat u de controle overdraagt ​​aan de aanroepende methode.

We krijgen de output:

Binnen, probeer het dan eindelijk eens

3.5. Methode Keert terug van vangst Blok

Wanneer de vangst blok bevat een terugkeer verklaring, de Tenslotte blok heet nog steeds:

probeer {System.out.println ("Inside try"); gooi nieuwe uitzondering (); } catch (uitzondering e) {System.out.println ("Inside catch"); terugkeer "van vangst"; } eindelijk {System.out.println ("Inside eindelijk"); }

Wanneer we een uitzondering gooien van de proberen block, het vangst block behandelt de uitzondering. Hoewel er een retourverklaring in het vangst block, voert de JVM het Tenslotte block voordat de controle wordt overgedragen aan de aanroepende methode, en het geeft het volgende weer:

Probeer binnenin eindelijk binnen te vangen

4. Wanneer Tenslotte Wordt niet uitgevoerd

Hoewel we altijd verwachten dat de JVM de verklaringen in een Tenslotte blok, zijn er enkele situaties waarin de JVM een Tenslotte blok.

We zouden al kunnen verwachten dat als het besturingssysteem ons programma stopt, het programma niet de kans krijgt om al zijn code uit te voeren. Er zijn ook enkele acties die we kunnen ondernemen om de uitvoering van een in behandeling zijnde Tenslotte blok.

4.1. Aanroepen System.exit

In dit geval beëindigen we de JVM door te bellen System.exit en daarom zal de JVM onze niet uitvoeren Tenslotte blok:

probeer {System.out.println ("Inside try"); System.exit (1); } eindelijk {System.out.println ("Inside eindelijk"); }

Dit levert:

Binnen proberen

4.2. Aanroepen stoppen

Gelijkwaardig aan System.exit, een oproep naar Runtime.halt stopt ook de uitvoering en de JVM voert er geen uit Tenslotte blokken:

probeer {System.out.println ("Inside try"); Runtime.getRuntime (). Halt (1); } eindelijk {System.out.println ("Inside eindelijk"); }

De output zal dus zijn:

Binnen proberen

4.3. Daemon Thread

Als een Daemon-thread de uitvoering van een probeer / eindelijk block en alle andere niet-daemon-threads worden afgesloten voordat de daemon-thread het Tenslotte block, wacht de JVM niet tot de daemon-thread de uitvoering van Tenslotte blok:

Runnable runnable = () -> {probeer {System.out.println ("Inside try"); } eindelijk {probeer {Thread.sleep (1000); System.out.println ("Inside eindelijk"); } catch (InterruptedException e) {e.printStackTrace (); }}}; Thread regular = nieuwe Thread (uitvoerbaar); Thread daemon = nieuwe Thread (uitvoerbaar); daemon.setDaemon (true); regular.start (); Thread.sleep (300); daemon.start ();

In dit voorbeeld is de uitvoerbaar afdrukken "Binnen proberen" zodra het de methode invoert en 1 seconde wacht voordat het afdrukt "Binnen eindelijk".

Hier beginnen we het regelmatig draad en de demon thread met een kleine vertraging. Wanneer de regelmatig thread voert het Tenslotte block, het demon thread wacht nog steeds binnen de proberen blok. Zoals de regelmatig thread voltooit de uitvoering en wordt afgesloten, de JVM wordt ook afgesloten en wacht niet op het demon thread om het Tenslotte blok.

Hier is de output:

Binnen proberen Binnen proberen Eindelijk proberen

4.4. JVM bereikt een oneindige lus

Hier is een proberen blok dat een oneindig bevat terwijl lus:

probeer {System.out.println ("Inside try"); while (true) {}} eindelijk {System.out.println ("Inside eindelijk"); }

Hoewel het niet specifiek is voor Tenslotte, is het vermeldenswaard dat als de proberen of vangst block bevat een oneindige lus, de JVM zal nooit een blok buiten die lus bereiken.

5. Veelvoorkomende valkuilen

Er zijn enkele veelvoorkomende valkuilen die we moeten vermijden wanneer we de Tenslotte blok.

Hoewel het volkomen legaal is, het wordt als een slechte gewoonte beschouwd om een terugkeer statement of gooi een uitzondering van een Tenslotte blok, en we moeten het koste wat het kost vermijden.

5.1. Negeert uitzondering

EEN terugkeer verklaring in de Tenslotte block negeert een niet-afgevangen uitzondering:

probeer {System.out.println ("Inside try"); gooi nieuwe RuntimeException (); } eindelijk {System.out.println ("Inside eindelijk"); terugkeer "van eindelijk"; }

In dit geval negeert de methode de RuntimeException gegooid en retourneert de waarde "Van eindelijk".

5.2. Negeert andere terugkeer Verklaringen

EEN terugkeer verklaring in de Tenslotte block negeert elke andere return-instructie in de proberen of vangst blok. Alleen de terugkeer verklaring in de Tenslotte block voert uit:

probeer {System.out.println ("Inside try"); terugkeer "van proberen"; } eindelijk {System.out.println ("Inside eindelijk"); terugkeer "van eindelijk"; }

In dit voorbeeld retourneert de methode altijd "Van eindelijk" en negeert volledig de terugkeer verklaring in de proberen blok. Dit kan een zeer moeilijke bug zijn om op te sporen, daarom moeten we het gebruik van terugkeer in Tenslotte blokken.

5.3. Verandert wat wordt gegooid of geretourneerd

Ook in het geval van het gooien van een uitzondering van een Tenslotte block, negeert de methode de gegenereerde uitzondering of terugkeer verklaringen in de proberen en vangst blokken:

probeer {System.out.println ("Inside try"); terugkeer "van proberen"; } eindelijk {gooi nieuwe RuntimeException (); }

Deze methode retourneert nooit een waarde en gooit altijd een RuntimeException.

Hoewel we misschien niet opzettelijk een uitzondering van de Tenslotte block zoals in dit voorbeeld, kunnen we dit probleem nog steeds tegenkomen. Het kan voorkomen wanneer opschoningsmethoden die we gebruiken in een Tenslotte blok gooi een uitzondering.

6. Conclusie

In dit artikel hebben we besproken wat Tenslotte blokken doen in Java en hoe ze te gebruiken. Vervolgens hebben we gekeken naar verschillende gevallen waarin de JVM ze uitvoert, en een paar gevallen waarin dit misschien niet het geval is.

Ten slotte hebben we gekeken naar enkele veelvoorkomende valkuilen bij gebruik Tenslotte blokken.

Zoals altijd is de broncode die in deze tutorial wordt gebruikt, beschikbaar op GitHub.