Câu trả lời:
Các ngoại lệ tồn tại để cho phép Xử lý ngoại lệ , có thể tránh sự cố nhưng nói chung là ngăn chặn hành vi hệ thống không mong muốn hoặc không thể đoán trước. Ví dụ, nếu kết nối chương trình của tôi với cơ sở dữ liệu hết thời gian, nó thường sẽ không làm sập hệ thống, nhưng nếu tôi phụ thuộc vào dữ liệu từ cơ sở dữ liệu, một ngoại lệ có thể cho phép tôi xử lý tình huống không có dữ liệu này khác với bình thường.
Nói theo mặc định, chương trình của tôi hiển thị một trang dữ liệu dựa trên những gì được trả về từ cơ sở dữ liệu - thật tệ, tôi không có dữ liệu. Thay vì trình bày một khung nhìn lộn xộn hoặc tiếp tục một hoạt động có khả năng không hợp lệ, tôi có thể bắt ngoại lệ này và quay lại cơ sở dữ liệu khác, đọc từ dữ liệu cục bộ, yêu cầu người dùng cung cấp dữ liệu hoặc trả lại cho người dùng hoặc hệ thống về trạng thái an toàn (có thể là một Điều đó sẽ không ngay lập tức gây ra ngoại lệ tương tự!)
Ngoài ra, trong các hệ thống mà đầu vào của người dùng có thể là nguyên nhân / giải pháp cho vấn đề, ngoại lệ có thể cho phép người dùng biết thông tin chi tiết và hữu ích về sự cố. Thay vì quá phổ biến "Một ngoại lệ chưa được xử lý xảy ra tại ..." hoặc "Thông báo lỗi đáng sợ trực tiếp từ SQL", bạn có thể nói với người dùng một cái gì đó hữu ích hoặc ít nhất có thể hiểu được như "Không thể kết nối với tài nguyên B."
Các ngoại lệ được tạo để đơn giản hóa việc xử lý lỗi. Không có ngoại lệ, logic xử lý lỗi phải được trải đều trong một ứng dụng. Bất kỳ chức năng nào có thể dẫn đến lỗi đều phải trả lại trạng thái lỗi và mỗi cuộc gọi phải được theo dõi bằng kiểm tra lỗi. Thông thường người gọi không thể làm gì hữu ích trong trường hợp có lỗi và chỉ có thể trả lại lỗi. Một nửa mã ứng dụng có thể được dành cho xử lý lỗi. Mã như vậy là vô cùng mong manh. Tất cả quá dễ dàng để bỏ qua kiểm tra lỗi và sự cố, hoặc tệ hơn là trả về kết quả không chính xác do lỗi không được chú ý.
Với các ngoại lệ, lỗi chỉ có thể được kiểm tra tại điểm có thể xử lý. Hầu hết các mã ứng dụng có thể được viết theo kiểu đường thẳng, vì các hàm sẽ trả về giá trị có thể sử dụng hoặc ném ngoại lệ.
Điểm của một ngoại lệ là thông báo cho người dùng về các trường hợp đặc biệt. Nếu có sự cố xảy ra với hệ thống, chương trình nên biết và được phép xử lý nó * một cách thích hợp.
Điều đó nói rằng, không, một ngoại lệ không tồn tại để ngăn hệ thống "sập". Một ngoại lệ là cho tôi biết có một vấn đề. Làm thế nào tôi tiến hành xác định có thể xác định nếu hệ thống "gặp sự cố".
Cũng lưu ý rằng một ngoại lệ không phải chấm dứt ứng dụng như bạn đã nói. Một ngoại lệ có thể được xử lý bởi lập trình viên và sửa chữa hoặc biến thành một số lỗi có ý nghĩa đối với người dùng.
* Việc sử dụng các ngoại lệ được kiểm tra (các ngoại lệ buộc phải bị bắt) là một điểm đau. Một số (có lẽ hầu hết) các nhà phát triển thấy rằng việc xử lý ngoại lệ bắt buộc là cồng kềnh, không cần thiết và chỉ là thực tiễn tồi.
Các ngoại lệ cho phép xử lý lỗi hiện đại bằng cách tách vị trí lỗi khỏi trình xử lý lỗi. Đôi khi điều này được sử dụng để kiểm soát dòng chảy quá.
Các trường hợp ngoại lệ chưa được xử lý chấm dứt một chương trình. Nhưng những điều này không khác với các trường hợp ngoại lệ trước đây, chỉ là một lập trình viên lười biếng quên đưa các trình xử lý lỗi thích hợp vào mọi đường dẫn khiến chúng hiển thị cho người dùng cuối. Tôi coi một chương trình bị chấm dứt bởi ngoại lệ giống như bất kỳ kết thúc bất ngờ nào khác.
Các hệ điều hành rất tốt trong việc dọn dẹp các quy trình bị hỏng cho dù chúng bị hỏng như thế nào, vì vậy các trường hợp ngoại lệ không thêm an toàn cho HĐH bằng bất kỳ cách nào khác ngoài việc chấm dứt các quy trình gặp trục trặc và giải phóng tài nguyên của chúng.
Nó rất đơn giản.
Trước khi các ngoại lệ được phát minh, mọi hàm phải trả về mã thoát (lỗi / thành công) và bất kỳ kết quả hoặc đầu ra nào từ hàm phải được truy xuất bằng cách chuyển nó một con trỏ tới bộ nhớ để được đặt bởi nó.
Vấn đề là nhiều lập trình viên đã không nhớ / bận tâm kiểm tra mã thoát sai cho từng chức năng và do đó các lỗi nghiêm trọng đôi khi bị bỏ qua, dẫn đến các hành vi khá khó giải thích.
Do đó, nó đã được quyết định - khi xảy ra lỗi, mà bạn không xem xét, gặp sự cố ngay lập tức! Xử lý ngoại lệ AKA.
Các ngoại lệ chỉ đơn giản là một cơ chế phát hiện lỗi. Tự chúng không có ích.
Nhưng bằng cách phát hiện lỗi, họ cho phép kích hoạt các cơ chế chống lỗi để phục hồi từ trạng thái lỗi bằng cách chuyển sang trạng thái không có lỗi (trạng thái trước hoặc trạng thái mới). Bằng cách đó, lỗi không được lan truyền đến các bộ phận khác của hệ thống.
Các ngoại lệ tồn tại để tách luồng chương trình bình thường (những gì chương trình được thiết kế để làm) khỏi luồng xử lý lỗi (cách chương trình đang cố gắng phục hồi từ một tình huống đặc biệt).
Điều này làm cho mã rõ ràng hơn và dễ bảo trì hơn.
Hãy xem xét hai đoạn mã:
try:
do1() # this is obvoiusly a normal
do2() # program flow
except:
oups() # this is exception handling code
So với cái này:
if foo():
thing1() # is this part of normal program flow?
else:
thing2() # or maybe this one? Or both? When?
Tất nhiên, xử lý ngoại lệ có thể được sử dụng để ngăn chương trình bị sập bằng cách:
try { // very bad code
my();
whole();
ugly();
application();
here();
} catch (Throwable t) {
// pretend it's ok
}
nhưng đây không phải là lý do cho các ngoại lệ trong các ngôn ngữ lập trình hiện đại.
Bạn cũng có thể sử dụng while
và break
thay vì if
nhưng đây không phải là những gì while
và break
là dành cho.