Como já foi respondido , é possível executar código e, em particular, chamar funções, após capturar a, StackOverflowError
pois o procedimento normal de tratamento de exceções da JVM desenrola a pilha entre throw
os catch
pontos e, liberando espaço de pilha para você usar. E sua experiência confirma que é o caso.
No entanto, isso não é exatamente o mesmo que dizer que, em geral, é possível recuperar de a StackOverflowError
.
A StackOverflowError
IS-A VirtualMachineError
, que IS-AN Error
. Como você observou, Java fornece alguns conselhos vagos para Error
:
indica problemas sérios que um aplicativo razoável não deve tentar detectar
e você, razoavelmente, conclui que deve soar como pegar um Error
pode estar OK em algumas circunstâncias. Observe que realizar um experimento não demonstra que algo é, em geral, seguro de fazer. Apenas as regras da linguagem Java e as especificações das classes que você usa podem fazer isso. A VirtualMachineError
é uma classe especial de exceção, porque a Java Language Specification e a Java Virtual Machine Specification fornecem informações sobre a semântica dessa exceção. Em particular, o último diz :
Uma implementação de Java Virtual Machine lança um objeto que é uma instância de uma subclasse da classe VirtualMethodError
quando um erro interno ou limitação de recurso a impede de implementar a semântica descrita neste capítulo. Esta especificação não pode prever onde erros internos ou limitações de recursos podem ser encontrados e não determina com precisão quando eles podem ser relatados. Assim, qualquer uma das VirtualMethodError
subclasses definidas abaixo podem ser lançadas a qualquer momento durante a operação da Java Virtual Machine:
...
StackOverflowError
Observação: A implementação da Java Virtual Machine ficou sem espaço de pilha para um encadeamento, normalmente porque o encadeamento está fazendo um número ilimitado de invocações recursivas como resultado de uma falha no programa em execução.
O problema crucial é que você "não pode prever" onde ou quando um StackOverflowError
será lançado. Não há garantias sobre onde ele não será lançado. Você não pode confiar que ele será lançado na entrada de um método, por exemplo. Pode ser lançado em um ponto dentro de um método.
Essa imprevisibilidade é potencialmente desastrosa. Como pode ser lançado dentro de um método, ele poderia ser lançado em parte por meio de uma sequência de operações que a classe considera uma operação "atômica", deixando o objeto em um estado parcialmente modificado e inconsistente. Com o objeto em um estado inconsistente, qualquer tentativa de usar esse objeto pode resultar em comportamento incorreto. Em todos os casos práticos, você não pode saber qual objeto está em um estado inconsistente, portanto, você deve assumir que nenhum objeto é confiável. Qualquer operação de recuperação ou tentativa de continuar após a exceção ser detectada pode, portanto, ter um comportamento incorreto. A única coisa segura a fazer é, portanto, não pegar umStackOverflowError
, mas sim para permitir que o programa seja encerrado. (Na prática, você pode tentar fazer algum registro de erros para ajudar na solução de problemas, mas não pode confiar que esse registro funcione corretamente). Ou seja, você não pode se recuperar de forma confiável de aStackOverflowError
.