Milyen esetben nem fut le a finally?

0 értékelés
63 megtekintés
BFrici (12 pont) kérdezte Okt 29.
A finally minden esetben lefut. Az lenne a kérdésem, hogy milyen esetben nem fut le mégsem?

2 Válasz

0 értékelés
tkiss Szakértő (308 pont) válaszolta meg Okt 30.
Krisz kiválasztva Nov 9.
 
Legjobb válasz

Szia!

Azon eseteket most tegyük félre, amikor mondjuk a programod el se jut a try block-ig, mert akkor a végtelenségig lehetne irreleváns eseteket sorolni. Alapjáraton kezeld úgy, hogy amennyiben a try block-ig eljutott a programod futása, úgy a finally is meg fog futni. Az természetesen befolyásolhatja a try-catch-finally kimenetét, ha egy exception-t nem kezelsz catch ágban, de attól még a finally megfut. Néhány eset alább:

  • Ha exception nem dobódik a try-ban és mind a try, mind pedig a finally visszatér egy értékkel,
    akkor a finally block-ban visszaadott értéket adja vissza(alább a "bbb" String-et):
        try
        {
            return "aaa";
        }
        finally {
            return "bbb";
        }
  • Ha dobódik exception a try-ban, és a finally szintén visszatér egy értékkel, akkor attól függetlenül hogy kezelted -e az Exception-t catch ágban, a finally által visszaadott értéket adja vissza(mindkét alábbi esetben "bbb"-t):
        try
        {
            throw new IllegalArgumentException("IllegalArgument thrown from try!");
        }
        finally {
            return "bbb";
        }

Itt megfut a catch block is, de a finally is:

        try
        {
            throw new IllegalArgumentException("IllegalArgument thrown from try!");
        }
        catch(IllegalArgumentException e)
        {
            System.out.println("IllegalArgument caught!");
            return "ccc";
        }
        finally {
            return "bbb";
        }
  • Meg kell különböztetni ugyanakkor azt az esetet, amikor a finally nem ad vissza értéket(mert mondjuk csak logolsz benne). Az alábbi esetben a finally is megfut, de utána a try-ban dobott exception-t is kidobja:
        try
        {
            throw new IllegalArgumentException("IllegalArgument thrown from try!");
        }
        finally {
            System.out.println("Finally block executed!");
        }
  • Viszont ha a try block és a finally is exception-t dob, akkor a finally-ben dobott kerül érvényre(alább a finally-ben dobott IllegalStateException dobódik):
        try
        {
            throw new IllegalArgumentException("IllegalArgument thrown from try!");
        }
        finally {
            throw new IllegalStateException("IllegalState thrown from finally!");
        }
Egyébként itt nagyon szépen szemléletesen mutatják be a finally lefutásának eseteit: https://programming.guide/java/try-finally.html
A kérdés viszont az volt, hogy mikor nem fut le. Valójában az oracle is óvatosan fogalmaz
ezügyben(https://docs.oracle.com/javase/tutorial/essential/exceptions/finally.html):
If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.
Tehát ha a JVM exitál, vagy a thread-et, ami a try-catch-finally-t végrehajtja megszakítják, akkor lehet, hogy nem fog megfutni a finally.
Ilyen esetek lehetnek az alábbiak:
  • Meghívod a System.exit-et a try futása alatt:
try
        {
            System.exit(0);
        }
        finally {
            System.out.println("Finally block executed!");
        }
  • Magát a thread-et lövöd ki:
        Thread t=new Thread(()->{
            
            try {
                Thread.sleep(10000);
            }
            catch (InterruptedException e) {
                e.printStackTrace();
            }
            finally {
                System.out.println("Finally block executed in thread!");
            }
        });
        
        t.start();
        t.stop();
  • Crash-el a JVM.
  • OS szinten lövöd le a JVM processzt.
  • Vagy ha áramtalanítod a gépet, úgy tuti nem fog lefutni smiley.
Üdv.: Tamás
0 értékelés
MarkB Guru (1,002 pont) válaszolta meg Okt 29.
Üdv,
A try, catch, finally ágak mind exception kezelésre valók.
A fianlly így ha minden exception el van kapva a catch block-ban minden esetben lefut.
Tehát kérdésedre válaszolva, csak akkor nem fut le a finally block, ha az aktuális exception nincs elkapva a catch-ben.
Pl.: ha catch (Exception e) - akkor minden esetben lefut a finally - mert minden féle exception-t elkaptál. Viszont ha például catch ( IOException ex ) és kapsz közben egy runtime exception-t, akkor az egy lekezeletlen exception. Ilyenkor a progi elszáll és a finally ágig nem jut el.
...