Come è già stato risposto , è possibile eseguire codice, ed in particolare chiamare funzioni, dopo aver catturato un StackOverflowError
perché la normale procedura di gestione delle eccezioni della JVM srotola lo stack tra throw
i catch
punti e, liberando spazio per lo stack da utilizzare. E il tuo esperimento conferma che è così.
Tuttavia, ciò non equivale a dire che, in generale, è possibile recuperare da a StackOverflowError
.
UN StackOverflowError
È-A VirtualMachineError
, che È-AN Error
. Come fai notare, Java fornisce alcuni vaghi consigli per Error
:
indica problemi seri che un'applicazione ragionevole non dovrebbe cercare di rilevare
e tu, ragionevolmente, concludi che dovrebbe sembrare catturare un Error
potrebbe essere OK in alcune circostanze. Nota che l'esecuzione di un esperimento non dimostra che qualcosa sia, in generale, sicuro da fare. Solo le regole del linguaggio Java e le specifiche delle classi che utilizzi possono farlo. A VirtualMachineError
è una classe speciale di eccezione, perché la specifica del linguaggio Java e il file Java Virtual Machine forniscono informazioni sulla semantica di questa eccezione. In particolare, quest'ultimo dice :
Un'implementazione di Java Virtual Machine genera un oggetto che è un'istanza di una sottoclasse della classe VirtualMethodError
quando un errore interno o una limitazione delle risorse impedisce di implementare la semantica descritta in questo capitolo. Questa specifica non può prevedere dove si possono incontrare errori interni o limitazioni di risorse e non impone esattamente quando possono essere segnalati. Pertanto, una qualsiasi delle VirtualMethodError
sottoclassi definite di seguito può essere generata in qualsiasi momento durante il funzionamento della Java Virtual Machine:
...
StackOverflowError
: L'implementazione della Java Virtual Machine ha esaurito lo spazio dello stack per un thread, in genere perché il thread sta eseguendo un numero illimitato di chiamate ricorsive a causa di un errore nel programma in esecuzione.
Il problema cruciale è che "non puoi prevedere" dove o quando StackOverflowError
verrà lanciato un testamento. Non ci sono garanzie su dove non verrà lanciato. Non puoi fare affidamento sul fatto che venga lanciato all'ingresso di un metodo, ad esempio. Potrebbe essere lanciato in un punto all'interno di un metodo.
Questa imprevedibilità è potenzialmente disastrosa. Poiché può essere lanciato all'interno di un metodo, potrebbe essere lanciato a metà di una sequenza di operazioni che la classe considera un'operazione "atomica", lasciando l'oggetto in uno stato parzialmente modificato, incoerente. Con l'oggetto in uno stato incoerente, qualsiasi tentativo di utilizzare quell'oggetto potrebbe provocare un comportamento errato. In tutti i casi pratici non puoi sapere quale oggetto si trova in uno stato incoerente, quindi devi presumere che nessun oggetto sia affidabile. Qualsiasi operazione di ripristino o tentativo di continuare dopo che l'eccezione è stata rilevata potrebbe quindi avere un comportamento errato. L'unica cosa sicura da fare è quindi non prendere un fileStackOverflowError
, ma piuttosto per consentire la chiusura del programma. (In pratica potresti tentare di eseguire una registrazione degli errori per aiutare la risoluzione dei problemi, ma non puoi fare affidamento sul fatto che la registrazione funzioni correttamente). Cioè, non puoi recuperare in modo affidabile da un fileStackOverflowError
.