Java Try Catch Finalmente si blocca senza Catch


125

Sto rivedendo del nuovo codice. Il programma ha solo una prova e un blocco finale. Poiché il blocco catch è escluso, come funziona il blocco try se incontra un'eccezione o qualcosa di lanciabile? Va solo direttamente al blocco finale?



25
@mP Tutti dovrebbero fare revisioni del codice e porre loro domande è come imparare e migliorare.
Carl Pritchett

Risposte:


130

Se uno qualsiasi del codice nel blocco try può generare un'eccezione controllata, deve comparire nella clausola throws della firma del metodo. Se viene generata un'eccezione non controllata, viene estratta dal metodo.

Il blocco finalmente viene sempre eseguito, indipendentemente dal fatto che venga generata un'eccezione o meno.


11
Il primo paragrafo non è necessariamente vero. I blocchi di prova possono essere annidati. Qualsiasi eccezione non rilevata, deselezionata o meno, uscirà dal metodo.
Andy Thomas

4
I blocchi di prova possono essere annidati, ma non lo consiglierei. Non scrivo codice in questo modo.
Duffymo

2
@ Duffymo: cosa significa "ribollito fuori dal metodo"?
OggiI guadagnato il

5
@ Anand solo un linguaggio leggermente non tecnico per "lanciare un'eccezione".
duffymo

2
Non ignorato; saltare la catena del metodo.
Duffymo

93

Una piccola nota su try/ finally: il finalmente verrà sempre eseguito a meno che

  • System.exit() è chiamato.
  • La JVM si blocca.
  • Il try{}blocco non finisce mai (es. Ciclo infinito).

4
Di cosa try{..} catch{ throw ..} finally{..}? Penso che alla fine non verrà eseguito
sbeliakov

10
In quel caso finalmente verrà comunque chiamato. Viene persa solo l'eccezione originale.
Peter Lawrey

Infine non verrà nemmeno eseguito se si chiama System.exit () prima.
mmirror

2
@jyw Questo è ciò che intendevo con il primo elemento nell'elenco sopra.
Peter Lawrey

Devo dire che questo copre tutte le basi!
Oscar Bravo

39

La specifica del linguaggio Java (1) descrive come try-catch-finallyviene eseguita. Non avere una presa equivale a non avere una presa in grado di prendere il Lanciabile dato.

  • Se l'esecuzione del blocco try viene completata bruscamente a causa di un lancio di un valore V, allora c'è una scelta:
    • Se il tipo di runtime di V è assegnabile al parametro di qualsiasi clausola catch dell'istruzione try, allora ...
      ...
    • Se il tipo di runtime di V non è assegnabile al parametro di alcuna clausola catch dell'istruzione try, viene eseguito il blocco finalmente . Poi c'è una scelta:
      • Se il blocco finalmente viene completato normalmente, l'istruzione try viene completata bruscamente a causa di un lancio del valore V.
      • Se il blocco finalmente viene completato bruscamente per il motivo S, l'istruzione try si completa bruscamente per il motivo S (e il lancio di valore V viene scartato e dimenticato).

(1) Esecuzione di try-catch-finalmente


16

L'interno infine viene eseguito prima di lanciare l'eccezione al blocco esterno.

public class TryCatchFinally {

  public static void main(String[] args) throws Exception {

    try{
        System.out.println('A');
        try{
            System.out.println('B');
            throw new Exception("threw exception in B");
        }
        finally
        {
            System.out.println('X');
        }
        //any code here in the first try block 
        //is unreachable if an exception occurs in the second try block
    }
    catch(Exception e)
    {
        System.out.println('Y');
    }
    finally
    {
        System.out.println('Z');
    }
  }
}

Risultati in

A
B
X
Y
Z

6

Il blocco finalmente viene sempre eseguito dopo la fine del blocco try, indipendentemente dal fatto che il blocco try termini normalmente o in modo anomalo a causa di un'eccezione, ehm, lanciabile.

Se viene generata un'eccezione da uno qualsiasi del codice all'interno del blocco try, il metodo corrente semplicemente rilancia (o continua a generare) la stessa eccezione (dopo aver eseguito il blocco latest).

Se il blocco finalmente genera un'eccezione / errore / lanciabile e c'è già un oggetto lanciabile in sospeso, diventa brutto. Francamente, dimentico esattamente cosa succede (tanto per la mia certificazione anni fa). Penso che entrambi gli oggetti lanciabili siano collegati insieme, ma c'è del voodoo speciale che devi fare (cioè - una chiamata al metodo che dovrei cercare) per ottenere il problema originale prima che il "finalmente" vomitato, ehm, vomiti.

Per inciso, provare / finalmente è una cosa abbastanza comune da fare per la gestione delle risorse, poiché java non ha distruttori.

Per esempio -

r = new LeakyThing();
try { useResource( r); }
finally { r.release(); }  // close, destroy, etc

"Finalmente", un altro consiglio: se non la briga di mettere in una cattura, sia specifica catch (atteso) sottoclassi throwable, o semplicemente catturare "Throwable", non "Eccezione", per un generale catch-all trap di errore. Troppi problemi, come gli errori di riflessione, generano "Errori", invece di "Eccezioni", e quelli scivoleranno a destra per qualsiasi "cattura tutto" codificato come:

catch ( Exception e) ...  // doesn't really catch *all*, eh?

fai questo invece:

catch ( Throwable t) ...

Vedi la risposta di Carlos Heuberger sotto per la parte brutta.
mplwork

3

Le versioni di Java precedenti alla 7 consentono queste tre combinazioni di try-catch-latest ...

try - catch
try - catch - finally
try - finally

finallyil blocco verrà sempre eseguito indipendentemente da cosa sta succedendo nel blocco tryo / e catch. quindi se non ci sono catchblocchi, l'eccezione non verrà gestita qui.

Tuttavia, avrai ancora bisogno di un gestore di eccezioni da qualche parte nel tuo codice, a meno che tu non voglia che la tua applicazione si blocchi completamente, ovviamente. Dipende dall'architettura della tua applicazione dove si trova esattamente il gestore.

  • Il blocco try Java deve essere seguito da catch o infine block.
  • Per ogni blocco try ci possono essere zero o più blocchi catch, ma solo un blocco alla fine.
  • Il blocco finalmente non verrà eseguito se il programma esce (chiamando System.exit () o causando un errore fatale che causa l'interruzione del processo).

1
"prima della versione 7 consente" stai insinuando che Java 7 e Java 8 non consentono queste tre combinazioni? Dubito che sia quello che intendi, ma è quello che implica la tua risposta.
Loduwijk

il blocco finalmente viene eseguito se c'è un'istruzione return nel blocco try?
Rahul Yadav

@Rahul Sì, finalmente sarà chiamato. Ref: stackoverflow.com/questions/65035/...
roottraveller

1
@Aaron - nuova sintassi per try-with-resource che chiama automaticamente .close () su qualsiasi cosa costruita tra parentesi subito dopo la parola chiave try.
Roboprog

2

come funziona il blocco try se incontra un'eccezione o qualcosa di lanciabile

L'eccezione viene lanciata fuori dal blocco, proprio come in ogni altro caso in cui non viene catturata.

Il blocco finale viene eseguito indipendentemente da come si esce dal blocco try, indipendentemente dal fatto che ci siano catture, indipendentemente dal fatto che ci sia o meno una cattura corrispondente.

I blocchi catch e infine sono parti ortogonali del blocco try. Puoi avere uno o entrambi. Con Java 7, non potrai avere nessuno dei due!


1

Non lo provi con quel programma? Verrà infine bloccato e verrà eseguito il blocco finale, ma l'eccezione non verrà gestita. Ma quell'eccezione può essere annullata nel blocco finalmente!


1

Il blocco finalmente viene eseguito dopo il completamento del blocco try. Se qualcosa viene lanciato all'interno del blocco try quando esce, il blocco finalmente viene eseguito.


0

All'interno del tryblocco scriviamo codici che possono generare un'eccezione. Il catchblocco è dove gestiamo l'eccezione. Il finallyblocco viene sempre eseguito indipendentemente dal fatto che si verifichi o meno un'eccezione.

Ora, se abbiamo il blocco try-finally invece del blocco try-catch-latest, l'eccezione non verrà gestita e dopo il blocco try invece del controllo che va a catturare il blocco andrà infine al blocco. Possiamo usare il blocco try-latest quando non vogliamo fare nulla con l'eccezione.


0

Indipendentemente dall'eccezione lanciata o meno nel tryblocco, il finallyblocco verrà eseguito. L'eccezione non sarebbe stata catturata.

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.