Sự khác nhau giữa Ngoại lệ và Lỗi


173

Tôi đang cố gắng tìm hiểu thêm về Java cơ bản và các loại Ném khác nhau, ai đó có thể cho tôi biết sự khác biệt giữa Ngoại lệ và Lỗi không?

Câu trả lời:


178

Lỗi không nên bị bắt hoặc xử lý (trừ trường hợp hiếm nhất). Ngoại lệ là bánh mì và bơ xử lý ngoại lệ. Các Javadoc giải thích nó cũng:

Lỗi là một lớp con của throwable 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 nắm bắt. Hầu hết các lỗi như vậy là điều kiện bất thường.

Nhìn vào một vài trong số các lớp con của Error, lấy một số nhận xét JavaDoc của chúng:

  • AnnotationFormatError - Ném khi trình phân tích chú thích cố gắng đọc chú thích từ tệp lớp và xác định rằng chú thích không đúng.
  • AssertionError - Ném để chỉ ra rằng một khẳng định đã thất bại.
  • LinkageError- Các lớp con của LinkageError chỉ ra rằng một lớp có một số phụ thuộc vào một lớp khác; tuy nhiên, lớp sau đã thay đổi một cách không thể thay đổi sau khi biên dịch lớp cũ.
  • VirtualMachineError - Ném để chỉ ra rằng Máy ảo Java bị hỏng hoặc đã hết tài nguyên cần thiết để nó tiếp tục hoạt động.

Thực sự có ba loại con quan trọng của Throwable:

  • Error - Một cái gì đó đủ nghiêm trọng đã sai, hầu hết các ứng dụng sẽ bị sập thay vì cố gắng xử lý sự cố,
  • Unchecked Exception (aka RuntimeException) - Rất thường xảy ra lỗi lập trình như một NullPointerExceptionđối số bất hợp pháp. Các ứng dụng đôi khi có thể xử lý hoặc khôi phục từ Throwabledanh mục này - hoặc ít nhất là bắt nó theo run()phương pháp của Thread , ghi nhật ký khiếu nại và tiếp tục chạy.
  • Đã kiểm tra Ngoại lệ (còn gọi là Mọi thứ khác) - Các ứng dụng được mong đợi có thể bắt và thực hiện một cách có ý nghĩa với phần còn lại, chẳng hạn như FileNotFoundExceptionTimeoutException...

10
Oracle nói rằng Unchecked exceptions != RuntimeExceptions; Unchecked exceptions = RuntimeExceptions + Errors. Tôi biết rằng nó đặt ra câu hỏi: Lỗi có phải là ngoại lệ không? , nhưng đây là những gì họ viết. Đây chỉ là một trong những ví dụ sau: docs.oracle.com/javase/tutorial/essential/exceptions/ .
ROMANIA_engineer

1
Câu hỏi chưa được trả lời là về bản chất RuntimeException và Error khác nhau như thế nào? Cả hai đều không được kiểm tra và bình đẳng theo mọi cách khác nhau.
Pacerier

38

Slide này hiển thị phân cấp ngoại lệ của Java bởi @ georgios-gousios giải thích chính xác sự khác biệt giữa Lỗi và Ngoại lệ trong Java.

Phân cấp ngoại lệ Java


6
Tôi rất thích nhìn thấy ai đó đang hồi phục sau một NullPulumException: D: D: D
Ignacio Soler Garcia

2
@IgnacioSolerGarcia Nó có thể và thậm chí còn có ý nghĩa (câu hỏi khác là nếu nó tốt). Thông thường bạn kiểm tra xem đối tượng có tồn tại không và sau đó gọi phương thức hoặc sử dụng trường. Nhưng bạn có thể thay vì kiểm tra sự tồn tại, hãy thử bắt NPE thay thế. Và đăng nhập một thông điệp về nó và tiếp tục, ví dụ.
Gangnus

@Gangnus: không có ý nghĩa. Hãy nhớ rằng một ngoại lệ bỏ qua các phần của mã và là một cách để báo cáo lỗi, không phải hoạt động bình thường
Ignacio Soler Garcia

17

Lỗi có xu hướng báo hiệu sự kết thúc của ứng dụng của bạn như bạn biết. Nó thường không thể được phục hồi từ và sẽ khiến VM của bạn thoát ra. Việc bắt chúng không nên được thực hiện ngoại trừ có thể đăng nhập hoặc hiển thị và thông báo phù hợp trước khi thoát.

Ví dụ: OutOfMemoryError - Bạn không thể làm gì nhiều vì chương trình của bạn không thể chạy được nữa.

Các ngoại lệ thường có thể phục hồi và ngay cả khi không, chúng thường chỉ có nghĩa là một hoạt động đã cố gắng thất bại, nhưng chương trình của bạn vẫn có thể tiếp tục.

Ví dụ: IllegalArgumentException - Truyền dữ liệu không hợp lệ cho một phương thức để cuộc gọi phương thức đó không thành công, nhưng nó không ảnh hưởng đến các hoạt động trong tương lai.

Đây là những ví dụ đơn giản và có rất nhiều thông tin khác chỉ riêng về Ngoại lệ.


Hãy xem example.javacodegeek.com/java-basics/exceptions/ Khăn làm ví dụ. IllegalArgumentException là ngoại lệ Runtime, không phải Lỗi. docs.oracle.com/javase/7/docs/api/java/lang/áp
Gangnus

8

Lỗi -

  1. Errors trong java là loại java.lang.Error .
  2. Tất cả các lỗi trong java là loại không được kiểm tra.
  3. Errors xảy ra vào thời gian chạy. Họ sẽ không được biết đến trình biên dịch.
  4. Không thể phục hồi từ các lỗi.
  5. Errors chủ yếu là do môi trường mà ứng dụng đang chạy.
  6. Ví dụ: java.lang.StackOverflowError ,java.lang.OutOfMemoryError

Ngoại lệ -

  1. Exceptions trong java là loại java.lang.Exception.
  2. Exceptions bao gồm cả loại được kiểm tra cũng như loại không được kiểm tra.
  3. Các ngoại lệ được kiểm tra được biết đến với trình biên dịch trong đó các ngoại lệ không được kiểm tra không được biết đến với trình biên dịch vì chúng xảy ra trong thời gian chạy.
  4. Bạn có thể phục hồi từ các ngoại lệ bằng cách xử lý chúng thông qua try-catch các khối.
  5. Exceptions chủ yếu được gây ra bởi chính ứng dụng.
  6. Ví dụ: Trường hợp ngoại lệ Checked: SQLException, IOException
    Exceptions không đánh dấu: ArrayIndexOutOfBoundException, ClassCastException,NullPointerException

đọc thêm: http://javaconceptoftheday.com/difference-b Among-error-vs-exception-in-java/ http://javaconceptoftheday.com/wp-content/uploads/2015/04/ErrorVsException.png



3

Mô tả về Errorlớp học khá rõ ràng:

An Errorlà một lớp con Throwable chỉ ra những vấn đề nghiêm trọng mà một ứng dụng hợp lý không nên cố gắng nắm bắt. Hầu hết các lỗi như vậy là điều kiện bất thường. Các ThreadDeath lỗi, mặc dù một điều kiện "bình thường", cũng là một lớp con củaError bởi vì hầu hết các ứng dụng không nên cố gắng nắm bắt nó.

Một phương thức không bắt buộc phải khai báo trong mệnh đề ném của nó, bất kỳ lớp con nào của Errornó có thể bị ném trong quá trình thực thi phương thức nhưng không bị bắt, vì các lỗi này là điều kiện bất thường không bao giờ xảy ra.

Trích dẫn từ tài liệuError riêng của lớp Java .

Nói tóm lại, bạn không nên bắt Errors, ngoại trừ bạn có lý do chính đáng để làm điều đó. (Ví dụ: để ngăn việc triển khai máy chủ web của bạn gặp sự cố nếu một servlet hết bộ nhớ hoặc một cái gì đó tương tự.)

ExceptionMặt khác, An chỉ là một ngoại lệ bình thường như trong bất kỳ ngôn ngữ hiện đại nào khác. Bạn sẽ tìm thấy một mô tả chi tiết trong tài liệu API Java hoặc bất kỳ tài nguyên trực tuyến hoặc ngoại tuyến nào.


2

Có một số điểm tương đồng và khác biệt giữa các lớp java.lang.Exceptionjava.lang.Error.

Điểm tương đồng:

  • Đầu tiên - cả lớp kéo dài java.lang.Throwablevà kết quả là kế thừa rất nhiều các phương pháp đó là phổ biến được sử dụng khi giao dịch với các lỗi như: getMessage, getStackTrace, printStackTracevà vân vân.

  • Thứ hai, vì là lớp con của java.lang.Throwablecả hai đều thừa hưởng các thuộc tính sau:

    • Bản thân throwable và bất kỳ lớp con nào của nó (bao gồm java.lang.Error) có thể được khai báo trong danh sách ngoại lệ phương thức bằng throwstừ khóa. Tuyên bố như vậy yêu cầu chỉ cho java.lang.Exceptionvà lớp con, cho java.lang.Throwable, java.lang.Errorjava.lang.RuntimeExceptionvà các lớp con của họ nó là không bắt buộc.

    • Chỉ java.lang.Throwablevà các lớp con được phép sử dụng trong catchmệnh đề.

    • Chỉ java.lang.Throwablevà các lớp con có thể được sử dụng với từ khóa - throw.

Kết luận từ thuộc tính này là theo cả hai java.lang.Errorjava.lang.Exceptioncó thể được khai báo trong tiêu đề phương thức, có thể là catchmệnh đề, có thể được sử dụng với từ khóa throw.

Sự khác biệt:

  • Sự khác biệt về khái niệm đầu tiên: java.lang.Errorđược thiết kế để ném bởi JVM và chỉ ra các vấn đề nghiêm trọng và có ý định dừng thực thi chương trình thay vì bị bắt (nhưng có thể như đối với bất kỳ java.lang.Throwablengười kế nhiệm nào khác ).

    Một đoạn từ mô tả javadoc về java.lang.Error:

    ... Chỉ ra những vấn đề nghiêm trọng mà một ứng dụng hợp lý không nên cố gắng nắm bắt.

    Ngược lại java.lang.Exceptionđược thiết kế để thể hiện các lỗi dự kiến ​​và có thể được xử lý bởi một lập trình viên mà không chấm dứt thực hiện chương trình.

    Một đoạn từ mô tả javadoc về java.lang.Exception:

    ... Chỉ ra các điều kiện mà một ứng dụng hợp lý có thể muốn nắm bắt.

  • Sự khác biệt thứ hai giữa java.lang.Errorjava.lang.Exceptionlần đầu tiên được coi là một ngoại lệ không được kiểm tra đối với kiểm tra ngoại lệ thời gian biên dịch. Vì mã kết quả ném java.lang.Errorhoặc các lớp con của nó không yêu cầu khai báo lỗi này trong tiêu đề phương thức. Trong khi ném java.lang.Exceptionkhai báo cần thiết trong tiêu đề phương thức.

Throwable và sơ đồ lớp kế thừa của nó (thuộc tính và phương thức được bỏ qua). nhập mô tả hình ảnh ở đây


1

IMO một lỗi là một cái gì đó có thể khiến ứng dụng của bạn bị lỗi và không nên xử lý. Một ngoại lệ là một cái gì đó có thể gây ra kết quả không thể đoán trước, nhưng có thể được phục hồi từ.

Thí dụ:

Nếu một chương trình đã hết bộ nhớ thì đó là một lỗi vì ứng dụng không thể tiếp tục. Tuy nhiên, nếu một chương trình chấp nhận một kiểu đầu vào không chính xác thì đó là một ngoại lệ vì chương trình có thể xử lý nó và chuyển hướng để nhận đúng kiểu đầu vào.


1

Lỗi chủ yếu là do môi trường mà ứng dụng đang chạy. Ví dụ, OutOfMemoryError xảy ra khi JVM hết bộ nhớ hoặc StackOverflowError xảy ra khi tràn ngăn xếp.

Các ngoại lệ chủ yếu được gây ra bởi chính ứng dụng. Ví dụ, NullPulumException xảy ra khi một ứng dụng cố gắng truy cập đối tượng null hoặc ClassCastException xảy ra khi một ứng dụng cố gắng truyền các loại lớp không tương thích.

Nguồn: Sự khác biệt giữa lỗi Vs Ngoại lệ trong Java


"Lỗi chủ yếu là do môi trường ứng dụng đang chạy" và "Ngoại lệ chủ yếu do chính ứng dụng gây ra" hoàn hảo!
ADJ

0

Đây là một bản tóm tắt khá hay từ API Java mà Lỗi và Ngoại lệ thể hiện:

Lỗi là một lớp con của throwable 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 nắm bắt. Hầu hết các lỗi như vậy là điều kiện bất thường. Lỗi ThreadDeath, mặc dù điều kiện "bình thường", cũng là một lớp con của Lỗi vì hầu hết các ứng dụng không nên cố gắng bắt lỗi.

Một phương thức không bắt buộc phải khai báo trong mệnh đề ném của nó bất kỳ lớp con Lỗi nào có thể bị ném trong quá trình thực thi phương thức nhưng không bị bắt, vì các lỗi này là điều kiện bất thường không bao giờ xảy ra.

OTOH, đối với trường hợp ngoại lệ, API Java cho biết:

Lớp Exception và các lớp con của nó là một dạng của throwable chỉ ra các điều kiện mà một ứng dụng hợp lý có thể muốn nắm bắt.


0

Lỗi được gây ra bởi môi trường nơi ứng dụng hoặc chương trình của bạn chạy. Hầu hết các lần, bạn có thể không phục hồi từ nó vì điều này kết thúc ứng dụng hoặc chương trình của bạn. Javadoc khuyên rằng bạn không nên bận tâm đến việc bắt các lỗi như vậy vì môi trường, ví dụ như JVM, các lỗi như vậy sẽ thoát ra.

Ví dụ: VirtualMachineError- Ném để chỉ ra rằng Máy ảo Java bị hỏng hoặc đã hết tài nguyên cần thiết để nó tiếp tục hoạt động. OutOfMemoryErrorxảy ra khi JVM hết bộ nhớ hoặc StackOverflowErrorxảy ra khi stack chạy qua.

Các ngoại lệ được gây ra bởi chính ứng dụng hoặc chương trình của bạn; có thể do sai lầm của bạn Hầu hết thời gian bạn có thể khôi phục từ nó và ứng dụng của bạn vẫn sẽ tiếp tục chạy. Bạn nên nắm bắt các lỗi đó để ngăn chặn việc chấm dứt bất thường ứng dụng hoặc chương trình của bạn và / hoặc có thể tùy chỉnh thông báo ngoại lệ để người dùng thấy một tin nhắn được định dạng độc đáo thay vì các thông báo ngoại lệ xấu mặc định nằm rải rác khắp nơi.

Ví dụ: NullPointerExceptionxảy ra khi một ứng dụng cố gắng truy cập đối tượng null. hoặc Cố gắng truy cập một mảng với chỉ mục không tồn tại hoặc gọi một hàm có dữ liệu hoặc tham số sai.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.