Làm cách nào để tạo các ngoại lệ tùy chỉnh trong Java? [đóng cửa]


149

Làm thế nào để chúng ta tạo các ngoại lệ tùy chỉnh trong Java?


2
Đó là phương pháp tương tự được sử dụng trong hầu hết các ngôn ngữ OO: mở rộng lớp Ngoại lệ cơ sở.
NDM


1) // Lớp đại diện cho lớp ngoại lệ do định nghĩa sử dụng MyException mở rộng Exception {public MyException (String s) {super (s); }} ------------------------------------------------ 2) thử {// Ném một đối tượng của ngoại lệ do người dùng xác định ném MyException mới ("TestException"); } Catch (MyException ex) {System.out.println ("Bị bắt"); // In thông báo từ đối tượng MyException System.out.println (ex.getMessage ()); }
Mandeep Yadav

Câu trả lời:


285

Để xác định một ngoại lệ được kiểm tra, bạn tạo một lớp con (hoặc phân cấp của các lớp con) của java.lang.Exception. Ví dụ:

public class FooException extends Exception {
  public FooException() { super(); }
  public FooException(String message) { super(message); }
  public FooException(String message, Throwable cause) { super(message, cause); }
  public FooException(Throwable cause) { super(cause); }
}

Các phương thức có khả năng ném hoặc truyền ngoại lệ này phải khai báo:

public void calculate(int i) throws FooException, IOException;

... và mã gọi phương thức này phải xử lý hoặc truyền bá ngoại lệ này (hoặc cả hai):

try {
  int i = 5;
  myObject.calculate(5);
} catch(FooException ex) {
  // Print error and terminate application.
  ex.printStackTrace();
  System.exit(1);
} catch(IOException ex) {
  // Rethrow as FooException.
  throw new FooException(ex);
}

Bạn sẽ nhận thấy trong ví dụ trên IOExceptionđược bắt và rút lại như FooException. Đây là một kỹ thuật phổ biến được sử dụng để đóng gói các ngoại lệ (thông thường khi triển khai API).

Đôi khi, sẽ có những tình huống mà bạn không muốn buộc mọi phương thức phải khai báo việc thực hiện ngoại lệ của mình trong mệnh đề ném của nó. Trong trường hợp này, bạn có thể tạo một ngoại lệ không được kiểm tra . Một ngoại lệ không được kiểm tra là bất kỳ ngoại lệ nào mở rộng java.lang.RuntimeException(chính nó là một lớp con của java.lang.Exception):

public class FooRuntimeException extends RuntimeException {
  ...
}

Các phương thức có thể ném hoặc truyền FooRuntimeExceptionngoại lệ mà không cần khai báo; ví dụ

public void calculate(int i) {
  if (i < 0) {
    throw new FooRuntimeException("i < 0: " + i);
  }
}

Các ngoại lệ không được kiểm tra thường được sử dụng để biểu thị lỗi lập trình viên, ví dụ: truyền một đối số không hợp lệ cho một phương thức hoặc cố gắng vi phạm giới hạn chỉ mục mảng.

Các java.lang.Throwablelớp học là gốc rễ của tất cả các lỗi và ngoại lệ có thể được ném trong Java. java.lang.Exceptionjava.lang.Errorlà cả hai lớp con của Throwable. Bất cứ điều gì mà các lớp con Throwablecó thể được ném hoặc bắt. Tuy nhiên, việc bắt hoặc ném thông thường là không tốt Errorvì điều này được sử dụng để biểu thị các lỗi bên trong đối với JVM mà thường không thể được "lập trình viên" xử lý (ví dụ OutOfMemoryError). Tương tự như vậy, bạn nên tránh bắt Throwable, điều này có thể dẫn đến việc bạn bắt Errorthêm Exceptions.


25
public class MyException extends Exception {
        // special exception code goes here
}

Ném nó như:

 throw new MyException ("Something happened")

Bắt như:

catch (MyException e)
{
   // something
}

4

Đối với một ngoại lệ được kiểm tra:

public class MyCustomException extends Exception { }

Về mặt kỹ thuật, mọi thứ mở rộng Throwableđều có thể bị ném, nhưng ngoại lệ thường là các phần mở rộng của Exceptionlớp để chúng được kiểm tra ngoại lệ (ngoại trừ RuntimeException hoặc các lớp dựa trên nó, không được kiểm tra), trái ngược với loại có thể ném khác,Error s thường không phải là thứ được thiết kế để được xử lý một cách duyên dáng ngoài các phần bên trong JVM.

Bạn cũng có thể đặt ngoại lệ không công khai, nhưng sau đó bạn chỉ có thể sử dụng chúng trong gói xác định chúng, trái ngược với các gói.

Theo như ném / bắt ngoại lệ tùy chỉnh, nó hoạt động giống như các ngoại lệ tích hợp - ném qua

throw new MyCustomException()

và bắt qua

catch (MyCustomException e) { }

4
RuntimeException mở rộng Ngoại lệ và không phải là ngoại lệ được kiểm tra.
Adamski

2
Về mặt kỹ thuật, bất cứ thứ gì kéo dài Throwableđều có thể được ném ra ; ngoại lệ mở rộng Exception. Một lớp con tùy chỉnh của throwable sẽ không bị bắt bởi một try { ... } catch (Exception e) { ... }khối.
Andrzej Doyle

Tại sao mọi người nâng cao câu trả lời này? Nó chứa một vài điểm không chính xác. 1) Bạn có thể không implmenet Throwable vì nó là một giao diện. 2) Bất cứ điều gì mở rộng Ném được KHÔNG phải là ngoại lệ ( Errorkhông phải là ngoại lệ, đó là lỗi). 3) Nó ngụ ý rằng bất kỳ lớp con Ngoại lệ nào đều được kiểm tra trong khi RuntimeException thì không. Câu trả lời được đưa ra bởi Adamski chính xác hơn nhiều!
oxbow_lakes

Rất tiếc - Tôi có nghĩa là ném có thể không phải là một giao diện tất nhiên!
oxbow_lakes

@oxbow_lakes - giải pháp lý tưởng sẽ là khắc phục những điểm không chính xác, phải không? Nhưng dù sao, tôi đã tự sửa chúng vì không ai làm thế.
Amber
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.