Wie bereits beantwortet wurde , ist es möglich, Code auszuführen und insbesondere Funktionen aufzurufen, nachdem a StackOverflowError
abgefangen wurde, da die normale Ausnahmebehandlungsprozedur der JVM den Stapel zwischen den throw
und den catch
Punkten abwickelt und so Stapelspeicherplatz für Sie frei macht. Und Ihr Experiment bestätigt, dass dies der Fall ist.
Dies ist jedoch nicht ganz das Gleiche wie die Aussage, dass es im Allgemeinen möglich ist, sich von a zu erholenStackOverflowError
.
Ein StackOverflowError
IS-A VirtualMachineError
, der IS-AN ist Error
. Wie Sie hervorheben, bietet Java einige vage Ratschläge für Error
:
weist auf schwerwiegende Probleme hin, die eine vernünftige Anwendung nicht abfangen sollte
und Sie kommen vernünftigerweise zu dem Schluss, dass es unter bestimmtenError
Umständen in Ordnung sein sollte , einen zu fangen . Beachten Sie, dass die Durchführung eines Experiments nicht zeigt, dass etwas im Allgemeinen sicher ist. Dies können nur die Regeln der Java-Sprache und die Spezifikationen der von Ihnen verwendeten Klassen. A VirtualMachineError
ist eine spezielle Ausnahmeklasse, da die Java-Sprachspezifikation und die Java Virtual Machine-Spezifikation Informationen zur Semantik dieser Ausnahme enthalten. Insbesondere sagt der letztere :
Eine Java Virtual Machine-Implementierung löst ein Objekt aus, das eine Instanz einer Unterklasse der Klasse ist, VirtualMethodError
wenn ein interner Fehler oder eine Ressourcenbeschränkung die Implementierung der in diesem Kapitel beschriebenen Semantik verhindert. Diese Spezifikation kann nicht vorhersagen, wo interne Fehler oder Ressourcenbeschränkungen auftreten können, und schreibt nicht genau vor, wann sie gemeldet werden können. Somit kann jede der VirtualMethodError
unten definierten Unterklassen jederzeit während des Betriebs der Java Virtual Machine ausgelöst werden:
...
StackOverflowError
: Der Implementierung der Java Virtual Machine ist der Stapelspeicher für einen Thread ausgegangen, normalerweise, weil der Thread aufgrund eines Fehlers im ausführenden Programm eine unbegrenzte Anzahl rekursiver Aufrufe ausführt.
Das entscheidende Problem ist, dass Sie "nicht vorhersagen können", wo oder wann ein StackOverflowError
Wurf geworfen wird. Es gibt keine Garantie dafür, wo es nicht geworfen wird. Sie können sich nicht darauf verlassen , dass es beispielsweise beim Eintritt in eine Methode ausgelöst wird . Es könnte an einem Punkt innerhalb einer Methode geworfen werden.
Diese Unvorhersehbarkeit ist möglicherweise katastrophal. Da es innerhalb einer Methode ausgelöst werden kann, kann es teilweise durch eine Folge von Operationen geworfen werden, die die Klasse als eine "atomare" Operation betrachtet, wodurch das Objekt in einem teilweise modifizierten, inkonsistenten Zustand belassen wird. Wenn sich das Objekt in einem inkonsistenten Zustand befindet, kann jeder Versuch, dieses Objekt zu verwenden, zu einem fehlerhaften Verhalten führen. In allen praktischen Fällen können Sie nicht wissen, welches Objekt sich in einem inkonsistenten Zustand befindet. Daher müssen Sie davon ausgehen, dass keine Objekte vertrauenswürdig sind. Jeder Wiederherstellungsvorgang oder Versuch, nach dem Abfangen der Ausnahme fortzufahren, kann daher ein fehlerhaftes Verhalten aufweisen. Das einzig sichere ist daher, a nicht zu fangenStackOverflowError
, sondern um das Programm beenden zu lassen. (In der Praxis versuchen Sie möglicherweise, eine Fehlerprotokollierung durchzuführen, um die Fehlerbehebung zu unterstützen. Sie können sich jedoch nicht darauf verlassen, dass diese Protokollierung ordnungsgemäß funktioniert.) Das heißt, Sie können sich nicht zuverlässig von einem erholenStackOverflowError
.