Como ya se ha respondido , es posible ejecutar código, y en particular llamar funciones, después de capturar un StackOverflowError
porque el procedimiento normal de manejo de excepciones de la JVM desenrolla la pila entre throw
los catch
puntos y, liberando espacio de pila para su uso. Y su experimento confirma que ese es el caso.
Sin embargo, eso no es lo mismo que decir que, en general, es posible recuperarse de un StackOverflowError
.
A StackOverflowError
IS-A VirtualMachineError
, que ES-AN Error
. Como señala, Java proporciona algunos consejos vagos para Error
:
Indica problemas graves que una aplicación razonable no debería intentar detectar.
y usted, razonablemente, llega a la conclusión de que deberíaError
parecer que atrapar y podría estar bien en algunas circunstancias. Tenga en cuenta que realizar un experimento no demuestra que, en general, algo sea seguro. Solo las reglas del lenguaje Java y las especificaciones de las clases que usa pueden hacer eso. A VirtualMachineError
es una clase especial de excepción, porque la Especificación del lenguaje Java y la Especificación de la máquina virtual Java proporcionan información sobre la semántica de esta excepción. En particular, este último dice :
La implementación de una máquina virtual de Java arroja un objeto que es una instancia de una subclase de la clase VirtualMethodError
cuando un error interno o una limitación de recursos le impide implementar la semántica descrita en este capítulo. Esta especificación no puede predecir dónde se pueden encontrar errores internos o limitaciones de recursos y no exige con precisión cuándo se pueden informar. Por lo tanto, cualquiera de las VirtualMethodError
subclases definidas a continuación puede lanzarse en cualquier momento durante el funcionamiento de la máquina virtual Java:
...
StackOverflowError
: La implementación de la máquina virtual Java se ha quedado sin espacio de pila para un subproceso, normalmente porque el subproceso está haciendo un número ilimitado de invocaciones recursivas como resultado de una falla en el programa en ejecución.
El problema crucial es que "no se puede predecir" dónde o cuándo se StackOverflowError
lanzará un . No hay garantías sobre dónde no se lanzará. No puede confiar en que se lance al ingresar a un método, por ejemplo. Podría lanzarse en un punto dentro de un método.
Esta imprevisibilidad es potencialmente desastrosa. Como se puede lanzar dentro de un método, podría lanzarse en parte a través de una secuencia de operaciones que la clase considera una operación "atómica", dejando el objeto en un estado parcialmente modificado, inconsistente. Con el objeto en un estado inconsistente, cualquier intento de usar ese objeto podría resultar en un comportamiento erróneo. En todos los casos prácticos, no puede saber qué objeto se encuentra en un estado inconsistente, por lo que debe asumir que ningún objeto es confiable. Por lo tanto, cualquier operación de recuperación o intento de continuar después de que se detecta la excepción podría tener un comportamiento erróneo. Por lo tanto, lo único seguro que puede hacer es no atraparStackOverflowError
, sino más bien para permitir que el programa termine. (En la práctica, puede intentar hacer un registro de errores para ayudar a solucionar problemas, pero no puede confiar en que el registro funcione correctamente). Es decir, no puede recuperarse de forma fiable de unStackOverflowError
.