Jak już odpowiedział , że jest to możliwe do wykonania kodu, a w szczególności do wywoływania funkcji po złapanie StackOverflowError
ponieważ normalny wyjątek procedury JVM obsługi odwija stos między throw
a catch
punkty, uwalniając stosu przestrzeń do użycia. Twój eksperyment potwierdza, że tak jest.
Nie jest to jednak to samo, co stwierdzenie, że generalnie można odzyskać od pliku StackOverflowError
.
A StackOverflowError
IS-A VirtualMachineError
, czyli IS-AN Error
. Jak zauważyłeś, Java zapewnia niejasne porady dotyczące Error
:
wskazuje na poważne problemy, których rozsądna aplikacja nie powinna próbować wychwycić
a ty, rozsądnie, dochodzisz do wniosku, że powinno to brzmieć jak złapanie, Error
może być w porządku w niektórych okolicznościach. Zwróć uwagę, że wykonanie jednego eksperymentu nie dowodzi, że ogólnie rzecz biorąc, coś jest bezpieczne. Mogą to zrobić tylko reguły języka Java i specyfikacje używanych klas. A VirtualMachineError
jest specjalną klasą wyjątku, ponieważ specyfikacja języka Java i specyfikacja maszyny wirtualnej języka Java zawierają informacje o semantyce tego wyjątku. W szczególności ten ostatni mówi :
Implementacja wirtualnej maszyny języka Java wyrzuca obiekt będący instancją podklasy klasy, VirtualMethodError
gdy błąd wewnętrzny lub ograniczenie zasobów uniemożliwia implementację semantyki opisanej w tym rozdziale. Ta specyfikacja nie pozwala przewidzieć, gdzie mogą wystąpić błędy wewnętrzne lub ograniczenia zasobów, i nie określa dokładnie, kiedy można je zgłosić. W związku z tym każda z VirtualMethodError
podklas zdefiniowanych poniżej może zostać wyrzucona w dowolnym momencie podczas działania wirtualnej maszyny języka Java:
...
StackOverflowError
: W implementacji wirtualnej maszyny języka Java zabrakło miejsca na stosie dla wątku, zazwyczaj dlatego, że wątek wykonuje nieograniczoną liczbę rekurencyjnych wywołań w wyniku błędu w wykonywanym programie.
Podstawowym problemem jest to, że „nie można przewidzieć”, gdzie i kiedy StackOverflowError
zostanie wyrzucony test. Nie ma gwarancji, gdzie nie zostanie wyrzucony. Nie można na przykład polegać na tym, że zostanie wyrzucony przy wejściu do metody. To może być rzucony w punkcie wewnątrz metody.
Ta nieprzewidywalność jest potencjalnie katastrofalna. Ponieważ może zostać wrzucony w ramach metody, może zostać wyrzucony w części przez sekwencję operacji, które klasa uważa za jedną operację „atomową”, pozostawiając obiekt w stanie częściowo zmodyfikowanym, niespójnym. Gdy obiekt znajduje się w niespójnym stanie, każda próba użycia tego obiektu może skutkować błędnym zachowaniem. We wszystkich praktycznych przypadkach nie możesz wiedzieć, który obiekt jest w niespójnym stanie, więc musisz założyć, że żadne obiekty nie są godne zaufania. Każda operacja odzyskiwania lub próba kontynuowania po przechwyceniu wyjątku może zatem mieć błędne zachowanie. Dlatego jedyną bezpieczną rzeczą jest nie złapanie plikuStackOverflowError
, ale raczej zezwolenie na zakończenie działania programu. (W praktyce możesz próbować rejestrować błędy, aby pomóc w rozwiązywaniu problemów, ale nie możesz polegać na tym, że rejestrowanie działa poprawnie). Oznacza to, że nie można niezawodnie odzyskać danych z plikuStackOverflowError
.