2016-01-11 21 views
6

Perché il risultato del seguente codice è 3, perché alla fine si arriva a terminare e uscire dal metodo anche se i controlli del compilatore cercano prima e perché il ritorno in prova non termina il metodo?try/finally senza catch con dichiarazione di ritorno?

public int returnVal(){ 
    try{ 
     return 2; 
    } 
    finally{ 
     return 3; 
    } 
} 
+1

Il blocco 'finally' viene sempre chiamato alla fine, è per questo che si chiama" finally "(pensa a" prova questo, prendi qualsiasi eccezione e finalmente fallo "). – Thomas

+2

Il blocco 'finally' è * sempre * eseguito a prescindere da cosa .. –

+0

sì, lo capisco, ma perché il compilatore ignora la dichiarazione di ritorno nel tentativo anche se ci arriva dentro in fase di esecuzione perché il ritorno in prova non lo fa terminare il metodo –

risposta

4

Vedi JLS 14.17

Si può notare, quindi, che l'istruzione return completa sempre bruscamente.

Le descrizioni precedenti dicono "tentativi di trasferimento controllo" anziché solo "controllo trasferimenti" perché se ci sono delle istruzioni try (§14.20) all'interno del metodo o del costruttore i cui blocchi try o catch contengono l'istruzione return, quindi infine, le proposizioni di quelle dichiarazioni di prova saranno eseguite, nell'ordine, più a fondo, più esterne, prima che il controllo venga trasferito all'invocatore del metodo o costruttore. Il completamento brusco di una clausola finally può interrompere il trasferimento del controllo avviato da una dichiarazione di ritorno.

Esplicitamente controllare le frasi attempts to transfer control e l'ultima frase. Il tentativo di ritorno tenta di trasferire il controller, aftwerwards infine il disrupt the transfer of control initiated by a return statement.

In altre parole, provare attempts to transfer the controll, ma poiché l'esecuzione del blocco finally è ancora aperta per l'esecuzione e contiene un'istruzione return il tentativo di trasferimento di controller nel blocco finally ha un valore più alto preceding. Ecco perché vedi il valore 3, che viene restituito all'interno del blocco finally.

4

finally viene eseguito prima di restituire il valore da try (o catch).

Se nel finally una dichiarazione return è presente sovrascrive il ritorno del blocco try (o catch).

Quindi anche in questo caso il ritorno di fine vince:

try { 
    // Exception thrown 
    return 2; 
} catch (Exception e) { 
    return 1; 
} finally { 
    return -1; // Always returns -1 also if a return statement is present in the try and in the catch clause 
} 
+0

+1 in quanto è stato molto più facile da capire rispetto alla risposta in alto (al prezzo di meno informazioni, ovviamente). – domsson

0

Il blocco finally viene sempre eseguito prima che il controllo venga restituito alla funzione di chiamata. Quindi in questo caso prima di restituire 2, chiamerà finalmente e restituirà 3.

1

Perché il ritorno in prova non termina il metodo?

Is it bad practice to return from within a try catch finally block?

bisogna essere consapevoli del fatto che quando si inserisce un ritorno all'interno di un'istruzione try-catch, il ritorno in sé è detenuto e gestito dal blocco di esibirci.

Il blocco eccezione memorizza solo il ritorno ed è veramente restituisce solo dopo tutte le verifiche sono fatto, il che non significa che il blocco finally sarà davvero avere un impatto sulla vostra ritorno:

public int returnVal() { 
    int i = 0; 
    try { 
     return i; 
    } 
    finally { 
     i = 99; 
    } 
} 

In In questo caso, il ritorno sarà sempre 0.

Ma nel caso in cui hai menzionato nella tua domanda, influenzi il ritorno una seconda volta, e poiché il blocco di eccezione non vuole lasciare il tuo ritorno fino a quando non è fatto con TUTTA la sua verifica, stai sempre memorizzando un valore di ritorno 2 volte nel tuo blocco di eccezioni. Il risultato sarà sempre 3.

Tieni presente che se inserisci un ritorno all'interno di try-catch-finally, tale ritorno non verrà restituito fino a quando il blocco definitivo non verrà eseguito; il ritorno stesso viene archiviato fino a quando tutto è stato verificato.