2015-02-22 2 views
5

Se generiamo un'eccezione nel metodo main e non la gestiamo funzionerà correttamente. In realtàChi gestisce effettivamente le eccezioni generate nel metodo principale?

public static void main(String[] args) throws IOException { 
    throw new IOException(); //OK 
} 

Ma Java richiede alcuna eccezione controllata da trattare nel programma, quindi la IOException dovrebbero essere gestite. Chi gestisce effettivamente l'IOException in quel caso?

Nota che la specifica del linguaggio Java definisce l'eccezione gestita se è racchiusa in un blocco try che contiene una clausola catch il tipo è un supertipo dell'eccezione.

+1

@KorayTugay Che cosa? Il tuo commento sembra essere assolutamente non costruttivo. – user3663882

+2

Downvoters, potresti spiegare perché? Ho chiesto spiegazioni formali sui principi operativi JVM – user3663882

+0

Sono sorpreso che questa domanda sia stata posta solo un anno fa e nessuno l'ha mai chiesto prima. Questa è sicuramente una buona domanda da porre. +1 – user3437460

risposta

9

Se non si sono intraprese azioni speciali per rilevare l'eccezione da soli, viene eseguito il valore uncaughtException predefinito .

Questo è specificato in JLS Chapter 11.3.

Se non è possibile trovare alcuna clausola di catch in grado di gestire un'eccezione, il thread corrente (il thread che ha rilevato l'eccezione) viene terminato. Prima di terminazione, tutti finalmente le clausole vengono eseguiti e l'eccezione non rilevata viene gestito secondo le seguenti regole:

  1. Se il thread corrente ha un set di gestore di eccezioni non intercettata, allora tale gestore viene eseguito.

  2. In caso contrario, il metodo uncaughtException viene invocato per lo ThreadGroup che è il genitore del thread corrente. Se lo ThreadGroup e la sua madre ThreadGroups non sostituiscono uncaughtException, , viene richiamato il metodo uncaughtException del gestore predefinito.

Inoltre javadoc di ThreadGroup.uncaughtException recita:

Chiamato dal Java Virtual Machine quando un thread in questo gruppo di discussione si interrompe a causa di un'eccezione non rilevata, e il filo non lo fa avere uno specifico Thread.UncaughtExceptionHandler installato.

Il uncaughtException metodo ThreadGroup esegue le seguenti operazioni:

  • Se questo gruppo filo ha un gruppo filo genitore, il metodo del genitore uncaughtException viene chiamato con gli stessi due argomenti.
  • In caso contrario, questo metodo controlla se è installato un gestore di eccezioni non rilevato predefinito e, in tal caso, il suo metodo uncaughtException viene chiamato con gli stessi due argomenti.
  • In caso contrario, questo metodo determina se l'argomento Throwable è un'istanza di ThreadDeath. Se è così, non viene fatto nulla di speciale. In caso contrario, un messaggio contenente il nome del thread, restituito dal metodo getName del thread e un backtrace dello stack, utilizzando il metodo printStackTraceThrowable, viene stampato sul flusso di errore standard.
+0

Quindi, in realtà se l'eccezione non è catturata da una clausola catch, verrà comunque gestita dalla JVM che chiama quel metodo. Questo spiega tutto. – user3663882

+1

Se un'eccezione non viene catturata da una clausola catch, la JVM lascerà che il ThreadGroup del thread di lancio (ovvero il thread che esegue 'main') gestisca l'eccezione. – aioobe

+0

Questa è l'unica spiegazione approfondita che può essere trovata nell'intero Internet sulla Terra. – user3437460

1

JVM gestisce direttamente le eccezioni generate da main().

+0

Perché la pensi così? Viene menzionato nella specifica Java o nella specifica Java Virtual Machine? – user3663882

+0

Non ricordo dove è menzionato. Ma è un tipo di conoscenza comune. – AlexR

+0

Beh, sto cercando una spiegazione formale di questo fatto. Giusto per essere sicuro che [questo] (http://docs.oracle.com/javase/specs/jls/se8/html/jls-11.html#jls-11.3) capitolo non lo menzioni. – user3663882

2

Se l'eccezione non viene rilevata, viene richiamato il gestore eccezioni non rilevate del gruppo di thread del thread o, e poi il filo termina.

Il JLS chapter 11 precisa che:

Se nessun catch clausola che può gestire un'eccezione può essere trovato, allora il thread corrente (il filo che ha rilevato l'eccezione) è terminato. Prima di terminazione, tutti finally clausole sono eseguiti e l'eccezione non rilevata viene gestita secondo le seguenti regole:

Se il thread corrente ha un set di gestore di eccezioni non intercettata, allora tale gestore viene eseguito.

In caso contrario, il metodo uncaughtException viene invocato per lo ThreadGroup che è il genitore del thread corrente. Se lo ThreadGroup principale non sostituisce uncaughtException, viene invocato il metodo del gestore predefinito.