Un blocco finally viene sempre eseguito in Java?


2382

Considerando questo codice, posso essere assolutamente sicuro che il finallyblocco venga sempre eseguito, qualunque cosa something()sia?

try {  
    something();  
    return success;  
}  
catch (Exception e) {   
    return failure;  
}  
finally {  
    System.out.println("I don't know if this will get printed out");
}

473
In caso contrario, la parola chiave dovrebbe essere probablyinvece denominata .
Noon Silk,




27
@BinoyBabu, finalizer ! = finally; finalizzatore == il finalize()metodo.
jaco0646,

Risposte:


2699

Sì, finallyverrà chiamato dopo l'esecuzione dei blocchi di codice tryo catch.

Le uniche volte finallyche non verranno chiamate sono:

  1. Se invochi System.exit()
  2. Se invochi Runtime.getRuntime().halt(exitStatus)
  3. Se la JVM si arresta per prima
  4. Se la JVM raggiunge un ciclo infinito (o qualche altra istruzione non interrompibile, non terminante) nel blocco tryocatch
  5. Se il sistema operativo termina forzatamente il processo JVM; ad es. kill -9 <pid>su UNIX
  6. Se il sistema host muore; ad es. mancanza di corrente, errore hardware, panico del sistema operativo, ecc
  7. Se il finallyblocco verrà eseguito da un thread daemon e tutti gli altri thread non daemon vengono chiusi prima della finallychiamata

44
In realtà thread.stop()non impedisce necessariamente finallyl'esecuzione del blocco.
Piotr Findeisen,

181
Che ne dici di dire che il finallyblocco verrà chiamato dopo il tryblocco e prima che il controllo passi alle seguenti istruzioni. Ciò è coerente con il blocco try che coinvolge un ciclo infinito e quindi il blocco finally non viene mai effettivamente invocato.
Andrzej Doyle,

9
c'è anche un altro caso, quando usiamo blocchi nidificati try-catch-finally
ruhungry,

7
inoltre, infine il blocco non viene chiamato in caso di eccezione generata dal thread demone.
Amrish Pandey,

14
@BinoyBabu - Si tratta del finalizzatore, non del blocco finale
avmohan

567

Codice di esempio:

public static void main(String[] args) {
    System.out.println(Test.test());
}

public static int test() {
    try {
        return 0;
    }
    finally {
        System.out.println("finally trumps return.");
    }
}

Produzione:

finally trumps return. 
0

18
Cordiali saluti: In C # il comportamento è identico a parte il fatto che non è consentito sostituire l'istruzione nella finallyclausola -clause return 2;(Errore del compilatore).
Alexander Pacha,

15
Qui è un dettaglio importante essere a conoscenza di: stackoverflow.com/a/20363941/2684342
WoodenKitty

18
Puoi anche aggiungere un'istruzione return nel blocco finally stesso, che quindi sovrascriverà il valore restituito precedente. Ciò scarta magicamente anche le eccezioni non gestite. A quel punto, dovresti considerare il refactoring del tuo codice.
Zyl,

8
Ciò non dimostra davvero che finalmente ritorna la briscola. Il valore restituito viene stampato dal codice chiamante. Non sembra dimostrare molto.
Trimtab,

20
Ci dispiace, ma questa è una dimostrazione non una prova. È solo una prova se puoi dimostrare che questo esempio si comporta sempre in questo modo su tutte le piattaforme Java e che esempi simili si comportano sempre in questo modo.
Stephen C

391

Inoltre, sebbene sia una cattiva pratica, se c'è un'istruzione return all'interno del blocco finally, vincerà qualsiasi altro ritorno dal blocco normale. Cioè, il seguente blocco restituirà false:

try { return true; } finally { return false; }

Stessa cosa con il lancio di eccezioni dal blocco finally.


95
Questa è davvero una brutta pratica. Vedi stackoverflow.com/questions/48088/… per maggiori informazioni sul perché è negativo.
John Meagher,

23
Concordato. Un ritorno entro {} ignora qualsiasi eccezione generata nel tentativo {}. ! spaventoso
neu242,

8
@ dominicbri7 Perché pensi che sia una pratica migliore? E perché dovrebbe essere diverso quando la funzione / metodo è nulla?
corsiKa,

8
Per lo stesso motivo non uso MAI goto nei miei codici C ++. Penso che i rendimenti multipli rendano più difficile la lettura e più difficile il debug (ovviamente in casi molto semplici non si applica). Immagino sia solo una preferenza personale e alla fine puoi ottenere la stessa cosa usando uno dei due metodi
dominicbri7,

16
Tendo a utilizzare un numero di resi quando si verifica un caso eccezionale. Come se (c'è un motivo per non continuare) ritorno;
iHearGeoff,

257

Ecco le parole ufficiali dalla specifica del linguaggio Java.

14.20.2. Esecuzione di try-finally e try-catch-finally

Una trydichiarazione con un finallyblocco viene eseguito in primo luogo l'esecuzione del tryblocco. Quindi c'è una scelta:

  • Se l'esecuzione del tryblocco si completa normalmente, [...]
  • Se l'esecuzione del tryblocco si completa bruscamente a causa throwdi un valore di V , [...]
  • Se l'esecuzione del tryblocco viene completata bruscamente per qualsiasi altro motivo R , il finallyblocco viene eseguito. Quindi c'è una scelta:
    • Se il blocco finally completa normalmente, quindi la trydichiarazione completa bruscamente per motivi R .
    • Se il finallyblocco si completa bruscamente per la ragione S , l' tryistruzione si completa bruscamente per la ragione S ( e la ragione R viene scartata ).

La specifica per returneffettivamente rende questo esplicito:

JLS 14.17 Dichiarazione di ritorno

ReturnStatement:
     return Expression(opt) ;

Una returndichiarazione con nessun Expression tentativo di trasferire il controllo al invoker del metodo o costruttore che lo contiene.

Una returndichiarazione con un Expression tentativo di trasferire il controllo all'invocatore del metodo che lo contiene; il valore di Expressiondiventa il valore dell'invocazione del metodo.

Le descrizioni precedenti dicono " tentativi di trasferire il controllo " anziché solo " trasferire il controllo " perché se trynel metodo o nel costruttore sono presenti istruzioni i cui tryblocchi contengono l' returnistruzione, tutte le finallyclausole di tali tryistruzioni verranno eseguite, nell'ordine più interno alla più esterna , prima che il controllo venga trasferito all'invocatore del metodo o del costruttore. Il completamento improvviso di una finallyclausola può interrompere il trasferimento del controllo avviato da una returndichiarazione.


163

Oltre alle altre risposte, è importante sottolineare che "finalmente" ha il diritto di sostituire qualsiasi eccezione / valore restituito dal blocco try..catch. Ad esempio, il codice seguente restituisce 12:

public static int getMonthsInYear() {
    try {
        return 10;
    }
    finally {
        return 12;
    }
}

Allo stesso modo, il seguente metodo non genera un'eccezione:

public static int getMonthsInYear() {
    try {
        throw new RuntimeException();
    }
    finally {
        return 12;
    }
}

Mentre il seguente metodo lo lancia:

public static int getMonthsInYear() {
    try {
        return 12;          
    }
    finally {
        throw new RuntimeException();
    }
}

63
Va notato che il caso centrale è precisamente il motivo per cui avere una dichiarazione di ritorno all'interno di un blocco finally è assolutamente orribile (potrebbe nascondere qualsiasi Lanciatore).
Dimitris Andreou,

2
Chi non vuole essere sorpreso OutOfMemoryError? ;)
RecursiveExceptionException

L'ho provato e sopprime un tale errore (yipes!). Genera anche un avviso quando lo compilo (yay!). E puoi aggirarlo definendo una variabile di ritorno e quindi usando return retVal dopo il finallyblocco, anche se questo ovviamente presuppone che tu abbia soppresso alcune altre eccezioni perché il codice non avrebbe senso altrimenti.
Maarten Bodewes,

120

Ho provato l'esempio sopra con una leggera modifica-

public static void main(final String[] args) {
    System.out.println(test());
}

public static int test() {
    int i = 0;
    try {
        i = 2;
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
    }
}

Il codice sopra riportato genera:

finalmente torna la briscola.
2

Questo perché quando return i;viene eseguito iha un valore 2. Successivamente finallyviene eseguito il blocco in cui 12 è assegnato ie quindi System.outviene eseguito out.

Dopo aver eseguito il finallyblocco, il tryblocco restituisce 2, anziché restituire 12, poiché questa istruzione return non viene eseguita nuovamente.

Se esegui il debug di questo codice in Eclipse, avrai la sensazione che dopo l'esecuzione System.outdel finallyblocco l' returnistruzione del tryblocco venga eseguita di nuovo. Ma non è così. Restituisce semplicemente il valore 2.


10
Questo esempio è fantastico, aggiunge qualcosa che non è stato menzionato in dozzine di thread finalmente correlati. Penso che quasi nessuno sviluppatore lo saprà.
Speriamo utile

4
E se inon fosse un oggetto primitivo, ma un intero.
Yamcha,

Sto facendo fatica a capire questo caso. docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.17 afferma che " Un'istruzione return con un'espressione tenta di trasferire il controllo all'invocatore del metodo o del corpo lambda che contiene esso .... Se la valutazione dell'Espressione si completa normalmente, producendo un valore V .. "Quello che potrei indovinare da questa affermazione è- sembra che il ritorno non valuti nuovamente l'espressione una volta valutato il valore V, ecco perché ho cambiato non influisce sul valore restituito, correggimi.
meexplorer,

Ma non ho trovato alcuna prova a riguardo, dove si dice che return non valuta di nuovo l'espressione.
meexplorer,

1
@meexplorer un po 'in ritardo, ma è spiegato in JLS 14.20.2. Esecuzione di try-finally e try-catch-finally - formulato un po 'complicato, 14.17. È necessario leggere anche la dichiarazione di
reso

117

Ecco un'elaborazione della risposta di Kevin . È importante sapere che l'espressione da restituire viene valutata prima finally, anche se viene restituita dopo.

public static void main(String[] args) {
    System.out.println(Test.test());
}

public static int printX() {
    System.out.println("X");
    return 0;
}

public static int test() {
    try {
        return printX();
    }
    finally {
        System.out.println("finally trumps return... sort of");
    }
}

Produzione:

X
finally trumps return... sort of
0

8
Importante da sapere.
Aminadav Glickshtein,

Buono a sapersi, e ha anche senso. Sembra che in realtà restituire il valore del rendimento sia ciò che viene dopo finally. Il calcolo del valore di ritorno ( printX()qui) viene ancora prima di esso.
Albert,

un buon esempio con tutti e 3 i punti "di ritorno"!
Radistao

No. Il codice sopra dovrebbe sostituire System.out.println("finally trumps return... sort of");conSystem.out.print("finally trumps return in try"); return 42;
Pacerier

54

Questa è l'idea di un blocco finalmente. Ti consente di assicurarti di fare pulizie che altrimenti potrebbero essere saltate perché, naturalmente, ritorni.

Alla fine viene chiamato indipendentemente da ciò che accade nel blocco try (a meno che non si chiami System.exit(int)o la Java Virtual Machine si avvii per qualche altro motivo).


Questa è una risposta estremamente debole. stackoverflow.com/a/65049/715269
Gangnus

42

Un modo logico di pensare a questo è:

  1. Il codice inserito in un blocco finally deve essere eseguito qualunque cosa avvenga all'interno del blocco try
  2. Quindi se il codice nel blocco try tenta di restituire un valore o genera un'eccezione, l'elemento viene posizionato "sullo scaffale" fino a quando il blocco finally può essere eseguito
  3. Poiché il codice nel blocco finally ha (per definizione) un'alta priorità, può restituire o lanciare quello che gli piace. In tal caso, tutto ciò che rimane "sullo scaffale" viene scartato.
  4. L'unica eccezione a ciò è se la VM si spegne completamente durante il blocco try, ad es. Con "System.exit"

10
È solo "un modo logico di pensarci" o è davvero come si intende che il blocco finally funzioni secondo le specifiche? Un collegamento a una risorsa Sun sarebbe molto interessante qui.
matias

21

infine viene sempre eseguito a meno che non ci sia una chiusura anomala del programma (come chiamare System.exit (0) ..). quindi, il tuo sysout verrà stampato



18

Il blocco finally viene sempre eseguito a meno che non vi sia una chiusura anomala del programma, risultante da un arresto anomalo della JVM o da una chiamata a System.exit(0).

Inoltre, qualsiasi valore restituito dall'interno del blocco finally sovrascriverà il valore restituito prima dell'esecuzione del blocco finally, quindi fai attenzione a controllare tutti i punti di uscita quando usi try finally.


18

No, non sempre un caso di eccezione è // System.exit (0); prima che il blocco finally ne impedisca l'esecuzione.

  class A {
    public static void main(String args[]){
        DataInputStream cin = new DataInputStream(System.in);
        try{
            int i=Integer.parseInt(cin.readLine());
        }catch(ArithmeticException e){
        }catch(Exception e){
           System.exit(0);//Program terminates before executing finally block
        }finally{
            System.out.println("Won't be executed");
            System.out.println("No error");
        }
    }
}

E questo è uno dei motivi per cui non dovresti mai chiamare System.exit () ...
Franz D.

13

Finalmente viene sempre eseguito questo è il punto, solo perché appare nel codice dopo il ritorno non significa che è così che viene implementato. Il runtime Java ha la responsabilità di eseguire questo codice all'uscita datry blocco.

Ad esempio se si dispone di quanto segue:

int foo() { 
    try {
        return 42;
    }
    finally {
        System.out.println("done");
    }
}

Il runtime genererà qualcosa del genere:

int foo() {
    int ret = 42;
    System.out.println("done");
    return 42;
}

Se viene generata un'eccezione non rilevata, il finallyblocco verrà eseguito e l'eccezione continuerà a propagarsi.


11

Questo perché hai assegnato il valore di i come 12, ma non hai restituito il valore di i alla funzione. Il codice corretto è il seguente:

public static int test() {
    int i = 0;
    try {
        return i;
    } finally {
        i = 12;
        System.out.println("finally trumps return.");
        return i;
    }
}

10

Perché un blocco finally verrà sempre chiamato a meno che non si chiami System.exit()(o il thread si arresti in modo anomalo).


10

In breve, nella documentazione ufficiale di Java (clicca qui ), è scritto che -

Se la JVM esce mentre viene eseguito il codice try o catch, il blocco finally potrebbe non essere eseguito. Allo stesso modo, se il thread che esegue il codice try o catch viene interrotto o ucciso, il blocco finally potrebbe non essere eseguito anche se l'applicazione nel suo insieme continua.


10

La risposta è semplice .

INGRESSO:

try{
    int divideByZeroException = 5 / 0;
} catch (Exception e){
    System.out.println("catch");
    return;    // also tried with break; in switch-case, got same output
} finally {
    System.out.println("finally");
}

PRODUZIONE:

catch
finally

1
La risposta è semplice NO.
Christophe Roussy,

1
@ChristopheRoussy Come? Puoi spiegare per favore?
Incontra il

1
leggi la risposta accettata, la domanda originale riguarda "Verrà sempre eseguita" e non sempre. Nel tuo caso, ma questo non risponde alla domanda originale e potrebbe anche essere un principiante fuorviante.
Christophe Roussy,

allora in che caso non verrà eseguito?
Incontro il

In tutti i casi menzionati in altre risposte, vedere la risposta accettata con oltre 1000 voti.
Christophe Roussy,

9

Sì, verrà chiamato. Questo è il punto centrale di avere una parola chiave finalmente. Se saltare dal blocco try / catch poteva semplicemente saltare il blocco infine, era come mettere System.out.println fuori dal tentativo / catch.


9

Sì, finalmente il blocco viene sempre eseguito. La maggior parte degli sviluppatori utilizza questo blocco per chiudere la connessione al database, l'oggetto resultset, l'oggetto statement e utilizza anche l'ibernazione Java per eseguire il rollback della transazione.


9

NON SEMPRE

La specifica Java Language descrive come try- catch- finallye try- catchblocchi di lavorare a 14.20.2
In nessun luogo si specifica che il finallyblocco viene sempre eseguito. Ma per tutti i casi in cui la try- catch- finallye try- finallyblocca completarlo non specifica che prima del completamento finallydeve essere eseguito.

try {
  CODE inside the try block
}
finally {
  FIN code inside finally block
}
NEXT code executed after the try-finally block (may be in a different method).

JLS non garantisce che FIN venga eseguito dopo CODICE . JLS garantisce che se CODE e NEXT vengono eseguiti, FIN sarà sempre eseguito dopo CODE e prima di NEXT .

Perché JLS non garantisce che il finallyblocco sia sempre eseguito dopo il tryblocco? Perché è impossibile. È improbabile ma possibile che la JVM venga interrotta (interruzione, arresto anomalo, spegnimento) subito dopo aver completato il tryblocco ma prima dell'esecuzione del finallyblocco. Non c'è nulla che JLS possa fare per evitarlo.

Pertanto, tutti i software che per il loro corretto comportamento dipendono dai finallyblocchi che vengono sempre eseguiti dopo il trycompletamento dei blocchi vengono intercettati.

returnle istruzioni nel tryblocco sono irrilevanti per questo problema. Se l'esecuzione raggiunge il codice dopo il try- catch- finallyè garantito che il finallyblocco sarà stato eseguito prima, con o senza returnistruzioni all'interno del tryblocco.


8

Si lo farà. Qualunque cosa accada nel tuo tentativo o cattura il blocco a meno che System.exit () altrimenti chiamato o JVM si sia arrestato in modo anomalo. se è presente un'istruzione return nei blocchi, verrà infine eseguita prima dell'istruzione return.


8

Si lo farà. L'unico caso in cui non lo sarà è l'uscita o l'arresto anomalo di JVM


8

Aggiungendo alla risposta di @ vibhash come nessun'altra risposta si spiega cosa succede nel caso di un oggetto mutevole come quello qui sotto.

public static void main(String[] args) {
    System.out.println(test().toString());
}

public static StringBuffer test() {
    StringBuffer s = new StringBuffer();
    try {
        s.append("sb");
        return s;
    } finally {
        s.append("updated ");
    }
}

Verrà emesso

sbupdated 

A partire da Java 1.8.162, questo non è l'output.
Sam

8

Ho provato questo, è a thread singolo.

public static void main(String args[]) throws Exception {
    Object obj = new Object();
    try {
        synchronized (obj) {
            obj.wait();
            System.out.println("after wait()");
        }
    } catch (Exception ignored) {
    } finally {
        System.out.println("finally");
    }
}

Lo stato main Threadsarà per waitsempre, quindi finallynon verrà mai chiamato ,

quindi l'output della console non lo farà print String: dopo wait()ofinally

Concordato con @Stephen C, l'esempio sopra è uno dei 3 casi citati qui :

Aggiungendo alcune altre possibilità di loop infiniti nel seguente codice:

// import java.util.concurrent.Semaphore;

public static void main(String[] args) {
    try {
        // Thread.sleep(Long.MAX_VALUE);
        // Thread.currentThread().join();
        // new Semaphore(0).acquire();
        // while (true){}
        System.out.println("after sleep join semaphore exit infinite while loop");
    } catch (Exception ignored) {
    } finally {
        System.out.println("finally");
    }
}

Caso 2: se la JVM si arresta per prima

import sun.misc.Unsafe;
import java.lang.reflect.Field;

public static void main(String args[]) {
    try {
        unsafeMethod();
        //Runtime.getRuntime().halt(123);
        System.out.println("After Jvm Crash!");
    } catch (Exception e) {
    } finally {
        System.out.println("finally");
    }
}

private static void unsafeMethod() throws NoSuchFieldException, IllegalAccessException {
    Field f = Unsafe.class.getDeclaredField("theUnsafe");
    f.setAccessible(true);
    Unsafe unsafe = (Unsafe) f.get(null);
    unsafe.putAddress(0, 0);
}

Rif: Come si blocca una JVM?

Caso 6: se il finallyblocco verrà eseguito dal demone Threade tutte le altre Threadsuscite non daemon prima verranno finallychiamate.

public static void main(String args[]) {
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            try {
                printThreads("Daemon Thread printing");
                // just to ensure this thread will live longer than main thread
                Thread.sleep(10000);
            } catch (Exception e) {
            } finally {
                System.out.println("finally");
            }
        }
    };
    Thread daemonThread = new Thread(runnable);
    daemonThread.setDaemon(Boolean.TRUE);
    daemonThread.setName("My Daemon Thread");
    daemonThread.start();
    printThreads("main Thread Printing");
}

private static synchronized void printThreads(String str) {
    System.out.println(str);
    int threadCount = 0;
    Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
    for (Thread t : threadSet) {
        if (t.getThreadGroup() == Thread.currentThread().getThreadGroup()) {
            System.out.println("Thread :" + t + ":" + "state:" + t.getState());
            ++threadCount;
        }
    }
    System.out.println("Thread count started by Main thread:" + threadCount);
    System.out.println("-------------------------------------------------");
}

output: Questo non stampa "finally", il che implica che "infine blocco" nel "thread demone" non è stato eseguito

main Thread Printing  
Thread :Thread[My Daemon Thread,5,main]:state:BLOCKED  
Thread :Thread[main,5,main]:state:RUNNABLE  
Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE   
Thread count started by Main thread:3  
-------------------------------------------------  
Daemon Thread printing  
Thread :Thread[My Daemon Thread,5,main]:state:RUNNABLE  
Thread :Thread[Monitor Ctrl-Break,5,main]:state:RUNNABLE  
Thread count started by Main thread:2  
-------------------------------------------------  

Process finished with exit code 0

4
Vedi la risposta accettata Questo è solo un caso limite di "loop infinito".
Stephen C

8

Considera il seguente programma:

public class SomeTest {

    private static StringBuilder sb = new StringBuilder();

    public static void main(String args[]) {

        System.out.println(someString());
        System.out.println("---AGAIN---");
        System.out.println(someString());
        System.out.println("---PRINT THE RESULT---");
        System.out.println(sb.toString());
    }

    private static String someString() {

        try {
            sb.append("-abc-");
            return sb.toString();

        } finally {
            sb.append("xyz");
        }
    }
}

A partire da Java 1.8.162, il blocco di codice sopra riportato fornisce il seguente output:

-abc-
---AGAIN---
-abc-xyz-abc-
---PRINT THE RESULT---
-abc-xyz-abc-xyz

ciò significa che l'utilizzo finallyper liberare oggetti è una buona pratica come il seguente codice:

private static String someString() {

    StringBuilder sb = new StringBuilder();

    try {
        sb.append("abc");
        return sb.toString();

    } finally {
        sb = null; // Just an example, but you can close streams or DB connections this way.
    }
}

Non dovrebbe essere sb.setLength(0)finalmente arrivato?
user7294900

sb.setLength (0) svuota semplicemente i dati in StringBuffer. Quindi, sb = null disassocia l'oggetto dal riferimento.
Sam,

"Xyz" non dovrebbe essere stampato due volte nell'output? Poiché la funzione è stata chiamata due volte, perché "finalmente" è stato solo una volta?
Fresko,

2
Questa non è una buona pratica. Quel blocco finalmente con sb = null;aggiunge solo il codice non necessario. Capisco che intendi dire che un finallyblocco è un buon posto per liberare risorse come una connessione al database o qualcosa del genere, ma ho in mente che il tuo esempio potrebbe confondere i nuovi arrivati.
Roc Boronat,

1
@Samim Grazie, ho aggiunto le righe System.out.println("---AGAIN2---"); System.out.println(sb);ed è più chiaro ora. In realtà, l'output era contrario alla tua tesi: p Ho anche aggiunto la tua risposta, ma la modifica deve essere accettata da un moderatore o da qualcuno del genere. Altrimenti puoi aggiungerli
fresko

7

Questo è vero in qualsiasi lingua ... infine verrà sempre eseguito prima di un'istruzione return, indipendentemente da dove si trovi quel ritorno nel corpo del metodo. Se così non fosse, il blocco finalmente non avrebbe molto significato.


7

Oltre al punto sul ritorno nel sostituire finalmente un ritorno nel blocco try, lo stesso vale per un'eccezione. Un blocco finally che genera un'eccezione sostituirà un ritorno o un'eccezione generata all'interno del blocco try.


7

finally verrà eseguito e questo è sicuro.

finally non verrà eseguito nei casi seguenti:

caso 1 :

Quando stai eseguendo System.exit().

caso 2:

Quando il tuo JVM / Thread si arresta in modo anomalo.

caso 3:

Quando la tua esecuzione viene interrotta tra manualmente.


6
  1. Finalmente Block viene sempre eseguito. A meno che e fino a quando System.exit () non esiste l'istruzione (prima istruzione nel blocco finally).
  2. Se system.exit () è la prima istruzione, infine il blocco non verrà eseguito e il controllo uscirà dal blocco finally. Ogni volta che l'istruzione System.exit () viene infine bloccata fino a quando l'istruzione non viene infine eseguita e quando appare System.exit (), la forza di controllo esce completamente dal blocco finally.

1
Questa è stata risposta molte volte, quindi quali nuove informazioni aggiunge la tua risposta?
Tom,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.