Sự khác biệt giữa java.lang.R.78Exception và java.lang.Exception


210

Ai đó hãy giải thích sự khác biệt giữa java.lang.RuntimeExceptionjava.lang.Exception? Làm cách nào để tôi quyết định mở rộng cái nào nếu tôi tạo ngoại lệ của riêng mình?

Câu trả lời:


181

Nói chung RuntimeExceptions là các ngoại lệ có thể được ngăn chặn bằng lập trình. Ví dụ NullPointerException, ArrayIndexOutOfBoundException. Nếu bạn kiểm tra nulltrước khi gọi bất kỳ phương thức nào, NullPointerExceptionsẽ không bao giờ xảy ra. Tương tự ArrayIndexOutOfBoundExceptionsẽ không bao giờ xảy ra nếu bạn kiểm tra chỉ số đầu tiên. RuntimeExceptionkhông được kiểm tra bởi trình biên dịch, vì vậy nó là mã sạch.

EDIT : Ngày nay mọi người ủng hộ RuntimeExceptionvì mã sạch mà nó tạo ra. Nó hoàn toàn là một lựa chọn cá nhân.


10
Tôi thích góc này của "người ngoại lệ thời gian chạy có thể tránh được người gọi". Điều đó có nghĩa là bạn (với tư cách là người gọi phương thức) được cho là đảm bảo chúng thậm chí không xảy ra. Trong khi các trường hợp ngoại lệ được kiểm tra là điều mà bạn không thể tránh và thay vào đó được yêu cầu xử lý chúng sau khi thực tế. (Và vâng, vì không phải ai cũng đồng ý với khái niệm ngoại lệ được kiểm tra và nhiều người sử dụng RuntimeException cho mọi thứ, sự khác biệt này đã trở nên hơi lộn xộn).
Thilo

4
Ngày nay mọi người cũng ủng hộ RuntimeException không được kiểm tra, bởi vì nó tương thích với xử lý Lambda của Java 8, trong khi các trường hợp ngoại lệ được kiểm tra loại Exception thì không.
Hartmut P.

2
Tôi nghi ngờ lý do thực sự mà mọi người nắm bắt RuntimeExceptionlà vì nó đơn giản và không cần phải suy nghĩ về sự khác biệt giữa các ngoại lệ được kiểm tra và không được kiểm tra. Tôi nghĩ rằng bắt các ngoại lệ trong thời gian chạy là một ý tưởng tồi tệ bởi vì bạn sẽ bắt được các ngoại lệ không thể phục hồi như NullPointerException.
Dónal

186

Trong Java, có hai loại ngoại lệ: ngoại lệ được kiểm tra và ngoại lệ không được kiểm tra. Một ngoại lệ được kiểm tra phải được xử lý rõ ràng bằng mã, trong khi đó, một ngoại lệ không được kiểm tra không cần phải được xử lý rõ ràng.

Đối với các ngoại lệ được kiểm tra, bạn phải đặt một khối thử / bắt xung quanh mã có khả năng ném ngoại lệ hoặc thêm mệnh đề "ném" vào phương thức, để chỉ ra rằng phương thức có thể ném loại ngoại lệ này (phải là xử lý trong lớp gọi trở lên).

Bất kỳ ngoại lệ nào xuất phát từ "Ngoại lệ" là một ngoại lệ được kiểm tra, trong khi một lớp xuất phát từ RuntimeException không được kiểm tra. RuntimeExceptions không cần phải được xử lý rõ ràng bằng mã gọi.


3
Thực tế đúng là "có hai loại ngoại lệ", nhưng tại sao tài liệu của Oracle nói có ba loại. Nó coi Lỗi là loại thứ 3. Tôi nghĩ rằng, Lỗi hoàn toàn không phải là Ngoại lệ, nó chỉ là throwable (object), vâng, nó bắt chước hành vi của các ngoại lệ thời gian chạy. Bạn sẽ nói gì về nó? Tài liệu Oracle. tham chiếu docs.oracle.com/javase/tutorial/essential/exceptions/ từ
Asif Shahzad

3
Lỗi không có nghĩa là bị bắt (mặc dù có thể như vậy) nói chung bạn sử dụng lỗi để bắt lỗi của chính mình khi bạn đang làm việc với mã mới. Chẳng hạn, nếu bạn có một cây nếu câu lệnh if / otherif, thì câu lệnh cuối cùng khác có thể chỉ xảy ra lỗi Ném ("không mong đợi điều kiện này xảy ra");. Nói chung, các trường hợp ngoại lệ có các trường hợp sử dụng trong đó chúng được CUNG CẤP xảy ra, trong khi các lỗi không có trường hợp sử dụng và chúng là một lỗi.
Daniel

5
Nhưng trò đùa là RunTimeException tự mở rộng Ngoại lệ: D (Tôi biết điều này không gây rắc rối gì và JVM quan tâm đến toàn bộ bối cảnh)
Alireza Mohamadi

94

Trước khi nhìn vào sự khác biệt giữa java.lang.RuntimeExceptionjava.lang.Exceptioncác lớp, bạn phải biết Exceptionthứ bậc. Cả hai ExceptionErrorcác lớp đều có nguồn gốc từ lớp Throwable(xuất phát từ lớp Object). Và lớp học RuntimeExceptioncó nguồn gốc từ lớp Exception.

Tất cả các ngoại lệ được bắt nguồn từ Exceptionhoặc RuntimeException.

Tất cả các ngoại lệ xuất phát từ RuntimeExceptionđược gọi là ngoại lệ không được kiểm tra . Và tất cả các ngoại lệ khác được kiểm tra ngoại lệ. Một ngoại lệ được kiểm tra phải được bắt gặp ở đâu đó trong mã của bạn, nếu không, nó sẽ không biên dịch. Đó là lý do tại sao chúng được gọi là ngoại lệ được kiểm tra. Mặt khác, với các ngoại lệ không được kiểm soát, phương thức gọi không có nghĩa vụ phải xử lý hoặc khai báo nó.

Do đó, tất cả các trường hợp ngoại lệ mà trình biên dịch buộc bạn phải xử lý đều có nguồn gốc trực tiếp java.lang.Exceptionvà tất cả các trường hợp khác mà trình biên dịch không buộc bạn phải xử lý đều bắt nguồn từ đó java.lang.RuntimeException.

Sau đây là một số lớp con trực tiếp được biết đến của RuntimeException .

AnnotationTypeMismatchException,
ArithmeticException,
ArrayStoreException,
BufferOverflowException,
BufferUnderflowException,
CannotRedoException,
CannotUndoException,
ClassCastException,
CMMException,
ConcurrentModificationException,
DataBindingException,
DOMException,
EmptyStackException,
EnumConstantNotPresentException,
EventException,
IllegalArgumentException,
IllegalMonitorStateException,
IllegalPathStateException,
IllegalStateException,
ImagingOpException,
IncompleteAnnotationException,
IndexOutOfBoundsException,
JMRuntimeException,
LSException,
MalformedParameterizedTypeException,
MirroredTypeException,
MirroredTypesException,
MissingResourceException,
NegativeArraySizeException,
NoSuchElementException,
NoSuchMechanismException,
NullPointerException,
ProfileDataException,
ProviderException,
RasterFormatException,
RejectedExecutionException,
SecurityException,
SystemException,
TypeConstraintException,
TypeNotPresentException,
UndeclaredThrowableException,
UnknownAnnotationValueException,
UnknownElementException,
UnknownTypeException,
UnmodifiableSetException,
UnsupportedOperationException,
WebServiceException 

47

Một ngoại lệ được kiểm tra và RuntimeException không được chọn.

Đã kiểm tra có nghĩa là trình biên dịch yêu cầu bạn xử lý ngoại lệ trong một lần bắt hoặc khai báo phương thức của bạn là ném nó (hoặc một trong các siêu lớp của nó).

Nói chung, ném ngoại lệ được kiểm tra nếu người gọi API dự kiến ​​sẽ xử lý ngoại lệ đó và ngoại lệ không được kiểm tra nếu đó là điều mà người gọi thường không thể xử lý, chẳng hạn như lỗi với một trong các tham số, tức là lập trình sai lầm.


15

Các lớp ngoại lệ thời gian chạy (RuntimeException và các lớp con của nó) được miễn kiểm tra thời gian biên dịch, vì trình biên dịch không thể thiết lập rằng các ngoại lệ thời gian chạy có thể xảy ra. (từ JLS).

Trong các lớp mà bạn thiết kế, bạn nên phân lớp Ngoại lệ và ném các thể hiện của nó để báo hiệu bất kỳ kịch bản đặc biệt nào. Làm như vậy bạn sẽ báo hiệu rõ ràng cho khách hàng của lớp rằng việc sử dụng lớp của bạn có thể tạo ra ngoại lệ và họ phải thực hiện các bước để xử lý các tình huống đặc biệt đó.

Đoạn mã dưới đây giải thích điểm này:

//Create your own exception class subclassing from Exception
class MyException extends Exception {
    public MyException(final String message) {
        super(message);
    }
}

public class Process {
    public void execute() {
        throw new RuntimeException("Runtime");
    }  
    public void process() throws MyException {
        throw new MyException("Checked");
    }
}

Trong định nghĩa lớp trên của lớp Process , phương thức executecó thể đưa ra RuntimeException nhưng khai báo phương thức không cần xác định rằng nó ném RuntimeException .

Phương thức processđưa ra một ngoại lệ được kiểm tra và nó sẽ tuyên bố rằng nó sẽ ném một ngoại lệ được kiểm tra thuộc loại MyException và không làm như vậy sẽ là một lỗi biên dịch.

Định nghĩa lớp trên cũng sẽ ảnh hưởng đến mã sử dụng lớp Process .

Cuộc gọi new Process().execute()là một lời gọi hợp lệ trong đó khi cuộc gọi của biểu mẫu new Process().process()đưa ra lỗi biên dịch. Điều này là do mã máy khách nên thực hiện các bước để xử lý MyException(có thể đặt lệnh gọi để xử lý () trong một khối thử / bắt).


13

Sử dụng RuntimeException đúng cách?

Từ các trường hợp ngoại lệ không được kiểm tra - Cuộc tranh cãi :

Nếu một khách hàng có thể được mong đợi phục hồi một cách hợp lý từ một ngoại lệ, hãy biến nó thành một ngoại lệ được kiểm tra. Nếu một khách hàng không thể làm bất cứ điều gì để phục hồi từ ngoại lệ, hãy biến nó thành một ngoại lệ không được kiểm soát.

Lưu ý rằng một ngoại lệ không được kiểm tra là một ngoại lệ bắt nguồn từ RuntimeExceptionvà một ngoại lệ được kiểm tra là một ngoại lệ bắt nguồn từ đó Exception.

Tại sao lại ném RuntimeExceptionnếu khách hàng không thể làm gì để phục hồi ngoại lệ? Bài viết giải thích:

Các ngoại lệ thời gian chạy thể hiện các vấn đề là kết quả của một vấn đề lập trình và do đó, mã máy khách API có thể được mong đợi một cách hợp lý để phục hồi từ chúng hoặc xử lý chúng theo bất kỳ cách nào. Những vấn đề như vậy bao gồm các ngoại lệ số học, chẳng hạn như chia cho số 0; ngoại lệ con trỏ, chẳng hạn như cố gắng truy cập một đối tượng thông qua tham chiếu null; và ngoại lệ lập chỉ mục, chẳng hạn như cố gắng truy cập một phần tử mảng thông qua một chỉ mục quá lớn hoặc quá nhỏ.


5

Từ tài liệu orory:

Đây là hướng dẫn quan trọng: Nếu một khách hàng có thể được mong đợi phục hồi một cách hợp lý từ một ngoại lệ, hãy biến nó thành một ngoại lệ được kiểm tra. Nếu một khách hàng không thể làm bất cứ điều gì để phục hồi từ ngoại lệ, hãy biến nó thành một ngoại lệ không được kiểm soát.

Các ngoại lệ thời gian chạy thể hiện các vấn đề là kết quả của một vấn đề lập trình và do đó, mã máy khách API có thể được mong đợi một cách hợp lý để phục hồi từ chúng hoặc xử lý chúng theo bất kỳ cách nào.

RuntimeExceptions giống như các trường hợp "ngoại lệ do sử dụng api không hợp lệ" của runtimeexceptions: IllegalStateException, NegativeArraySizeException, NullpulumException

Với Ngoại lệ, bạn phải nắm bắt rõ ràng vì bạn vẫn có thể làm gì đó để khôi phục. Ví dụ về các trường hợp ngoại lệ là: IOException, TimeoutException, PrintException ...


4

Nói một cách đơn giản, nếu khách hàng / người dùng của bạn có thể khôi phục từ Ngoại lệ thì hãy biến nó thành Ngoại lệ được kiểm tra , nếu khách hàng của bạn không thể làm gì để khôi phục từ Ngoại lệ thì hãy bỏ chọn RuntimeException . Ví dụ, RuntimeException sẽ là một lỗi lập trình, như chia cho số 0, không người dùng nào có thể làm bất cứ điều gì ngoài bản thân người lập trình, thì đó là RuntimeException .


3

RuntimeException là một lớp con của lớp Exception

Đây là một trong nhiều lớp con của lớp Exception. RuntimeException là siêu lớp của những ngoại lệ có thể được ném trong quá trình hoạt động bình thường của Máy ảo Java. 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 RuntimeException có thể bị ném trong quá trình thực thi phương thức nhưng không bị bắt.

Các chữ tượng hình là

java.lang.Object

--- java.lang.Throwable

------- java.lang.Exception

------------- java.lang.R.78Exception


0

Ngoại lệ là một cách tốt để xử lý các sự kiện bất ngờ trong luồng ứng dụng của bạn. RuntimeException không được kiểm tra bởi Trình biên dịch nhưng bạn có thể thích sử dụng Ngoại lệ mở rộng Lớp ngoại lệ để kiểm soát hành vi của các máy khách api của bạn vì chúng bắt buộc phải bắt lỗi để chúng biên dịch. Cũng hình thành tài liệu tốt.

Nếu muốn đạt được giao diện sạch, hãy sử dụng tính kế thừa để phân lớp các loại ngoại lệ khác nhau mà ứng dụng của bạn có và sau đó phơi bày ngoại lệ cha.


0

Có hai loại ngoại lệ, Bạn có thể khôi phục từ ngoại lệ được kiểm tra nếu bạn nhận được loại ngoại lệ đó. Ngoại lệ thời gian chạy là không thể phục hồi, ngoại lệ thời gian chạy là lỗi lập trình và lập trình viên nên xử lý nó trong khi viết mã và tiếp tục thực hiện điều này có thể cho bạn kết quả không chính xác. Ngoại lệ thời gian chạy là về vi phạm điều kiện tiên quyết. bạn có một mảng có kích thước 10 và bạn đang cố truy cập vào phần tử thứ 11, nó sẽ ném ArrayIndexOutOfBoundException


0
  1. Ngoại lệ do người dùng định nghĩa có thể được kiểm tra Ngoại lệ hoặc Ngoại lệ không được kiểm tra, Nó phụ thuộc vào lớp mà nó được mở rộng.

  2. Ngoại lệ do người dùng định nghĩa có thể là Ngoại lệ được kiểm tra tùy chỉnh, nếu nó được mở rộng sang lớp Ngoại lệ

  3. Ngoại lệ do người dùng định nghĩa có thể là Ngoại lệ không được kiểm tra tùy chỉnh, nếu nó đang mở rộng sang lớp Ngoại lệ thời gian chạy.

  4. Xác định một lớp và biến nó thành một đứa trẻ để Ngoại lệ hoặc Chạy thời gian Ngoại lệ

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.