Như đã được trả lời , có thể thực thi mã, và cụ thể là gọi các hàm, sau khi bắt được a StackOverflowError
vì thủ tục xử lý ngoại lệ bình thường của JVM giải nén ngăn xếp giữa hàm throw
vàcatch
giải phóng ngăn điểm, giải phóng không gian ngăn xếp cho bạn sử dụng. Và thử nghiệm của bạn xác nhận rằng đúng như vậy.
Tuy nhiên, điều đó không hoàn toàn giống với việc nói rằng, nói chung, có thể phục hồi từStackOverflowError
.
A StackOverflowError
IS-A VirtualMachineError
, IS-AN Error
. Như bạn đã chỉ ra, Java cung cấp một số lời khuyên mơ hồ cho Error
:
chỉ ra các vấn đề nghiêm trọng mà một ứng dụng hợp lý không nên cố gắng bắt
và bạn, một cách hợp lý, kết luận rằng nên âm thanh như bắt một Error
có thể là OK trong một số trường hợp. Lưu ý rằng việc thực hiện một thử nghiệm không chứng minh rằng điều gì đó nói chung là an toàn để thực hiện. Chỉ các quy tắc của ngôn ngữ Java và các đặc tả của các lớp bạn sử dụng mới có thể làm được điều đó. A VirtualMachineError
là một lớp ngoại lệ đặc biệt, bởi vì Đặc tả ngôn ngữ Java và Đặc tả máy ảo Java cung cấp thông tin về ngữ nghĩa của ngoại lệ này. Đặc biệt, sau này nói :
Một triển khai Máy ảo Java ném một đối tượng là một thể hiện của lớp con của lớp VirtualMethodError
khi một lỗi nội bộ hoặc giới hạn tài nguyên ngăn cản nó triển khai ngữ nghĩa được mô tả trong chương này. Đặc điểm kỹ thuật này không thể dự đoán nơi có thể gặp phải các lỗi nội bộ hoặc các giới hạn về nguồn lực và không bắt buộc phải báo cáo chính xác khi nào chúng có thể được báo cáo. Do đó, bất kỳ VirtualMethodError
lớp con nào được định nghĩa dưới đây có thể được ném vào bất kỳ lúc nào trong quá trình vận hành Máy ảo Java:
...
StackOverflowError
: Việc triển khai Máy ảo Java đã hết không gian ngăn xếp cho một luồng, thường là do luồng đang thực hiện một số lượng lệnh gọi đệ quy không giới hạn do lỗi trong chương trình đang thực thi.
Vấn đề quan trọng là bạn "không thể đoán trước" vị trí hoặc khi nào một StackOverflowError
sẽ được ném. Không có gì đảm bảo về nơi nó sẽ không bị ném. Bạn không thể dựa vào nó bị ném vào entry đến một phương pháp, ví dụ. Nó có thể được ném vào một điểm trong một phương thức.
Sự khó lường này tiềm ẩn rất nhiều tai họa. Vì nó có thể được ném bên trong một phương thức, nó có thể được ném từng phần thông qua một chuỗi hoạt động mà lớp coi là một hoạt động "nguyên tử", khiến đối tượng ở trạng thái đã sửa đổi một phần, không nhất quán. Với đối tượng ở trạng thái không nhất quán, bất kỳ nỗ lực nào để sử dụng đối tượng đó đều có thể dẫn đến hành vi sai lầm. Trong mọi trường hợp thực tế bạn không thể biết mà đối tượng đang ở trong một trạng thái không phù hợp, vì vậy bạn phải thừa nhận rằng không có đối tượng là đáng tin cậy. Do đó, bất kỳ hoạt động khôi phục nào hoặc nỗ lực tiếp tục sau khi bắt được ngoại lệ đều có thể có hành vi sai. Do đó, điều an toàn duy nhất cần làm là không bắtStackOverflowError
, mà là để cho phép chương trình kết thúc. (Trong thực tế, bạn có thể cố gắng thực hiện một số lỗi ghi nhật ký để hỗ trợ khắc phục sự cố, nhưng bạn không thể dựa vào việc ghi nhật ký đó hoạt động chính xác). Đó là,bạn không thể phục hồi đáng tin cậy từ aStackOverflowError
.