Java: Ngoại lệ tự định nghĩa

Lưu ý và cách tạo ngoại lệ tự định nghĩa

Ta có thể cân nhắc việc tạo một lớp ngoại lệ tùy chỉnh riêng của ta khi:

  • Kiểu ngoại lệ cài sẵn không đáp ứng yêu cầu.
  • Cần phải phân biệt các ngoại lệ của ta với các ngoại lệ do các lớp được viết bởi các nhà cung cấp khác.
  • Khối mã lệnh ném nhiều hơn một ngoại lệ liên quan.

Lưu ý là lớp ngoại lệ do ta tạo ra phải kế thừa từ lớp Exception.

Cú pháp như sau:

public class

<

ExceptionName

>

extends

Exception {}

Ví dụ:

public class

ServerException

extends

Exception

{

public

ServerException

() { } // Override phương thức getMessage()

@Override

public

String

getMessage

() // line 1 {

return

"K

ế

t n

i không thành công"

; } }

Giải thích:

ServerException là một lớp ngoại lệ do người dùng định nghĩa kế thừa từ lớp Exception có sẵn.

Phương thức getMessage() của lớp Exception đã được ghi đè trong lớp ServerException để in thông báo do người dùng định nghĩa “Kết nối không thành công”.

Ném ngoại lệ tự định nghĩa

Để sử dụng ngoại lệ do người dùng định nghĩa, một phương thức phải ném ngoại lệ vào thời gian chạy.

Ngoại lệ được chuyển tiếp lên trong ngăn xếp lời gọi và được xử lý tại nơi gọi phương thức.

Ví dụ sau sẽ giải thích cách ném một ngoại lệ tự định nghĩa:

package

solutions

;

public class

ServerException

extends

Exception

{

public

ServerException

() { } // Override phương thức getMessage()

@Override

public

String

getMessage

() // line 1 {

return

"K

ế

t n

i không thành công"

; } }

class

MyConnection

{

String

ip

;

String

port

;

public

MyConnection

() { }

public

MyConnection

(

String

ip,

String

port) {

this

.

ip

= ip;

this

.

port

= port; } // tạo một phương thức để ném ngoại lệ tự định nghĩa

public void

connectToServer

()

throws

ServerException

{

if

(

ip

.equals(

"127.10.10.1"

) &&

port

.equals(

"123456"

))

System

.out.println(

"Đang k

ế

t n

i Server …"

);

else

throw new

ServerException(); // ném ngoại lệ tự định nghĩa } //Hàm main()

public static void

main

(

String

[] args) {

MyConnection myConnection

=

new

MyConnection(

"127.0.0.1"

,

"123456"

);

try

{

myConnection

.connectToServer(); }

catch

(

ServerException

se) {

System

.out.println(se.getMessage()); } } }

Giải thích:

Trong ví dụ trên, tại phương thức connectToServer(), nếu điều kiện ip.equals(“127.10.10.1”) && port.equals(“123456”) không được đáp ứng thì sẽ ném ngoại lệ ServerException là ngoại lệ do ta tự định nghĩa.

Gộp các ngoại lệ

Gộp ngoại lệ tức là bắt một ngoại lệ, gộp nó vào trong một ngoại lệ khác rồi ném ngoại lệ được gộp đó.

Gói ngoại lệ là một tính năng tiêu chuẩn trong Java từ version JDK 1.4.

Hầu hết các ngoại lệ tích hợp sẵn của Java đều có các hàm tạo có thể nhận tham số ‘cause’.

Những ngoại lệ tích hợp sẵn này cũng cung cấp phương thức getCause() sẽ trả về ngoại lệ được gộp.

Lý do chính của việc gộp ngoại lệ là để ngăn không cho ngăn xếp lời gọi biết về mọi ngoại lệ có thể có trong hệ thống.

Ngoài ra, người ta có thể không muốn các thành phần cấp cao nhất biết bất kỳ điều gì về các thành phần cấp dưới và các ngoại lệ mà chúng ném ra.

Ví dụ:

package

solutions

; // tạo lớp ngoại lệ riêng

class

CalculatorException

extends

Exception

{

public

CalculatorException

() { } // hàm tạo với tham số là đối tượng Throwable

public

CalculatorException

(

Throwable

cause) {

super

(cause); } // hàm tạo với tham số gồm một chuỗi thông báo và một đối tượng Throwable

public

CalculatorException

(

String

message,

Throwable

cause) {

super

(message, cause); } } // tạo lớp Calculator

class

Calculator

{ // phương thức chia hai số

public void

divide

(

int

a,

int

b)

throws

CalculatorException

{ // khối try-catch

try

{

int

result

= a / b; // tiến hành chia

System

.out.println(

"K

ế

t qu

: "

+

result

); }

catch

(

ArithmeticException

ex) { // ném ngoại lệ gộp

throw new

CalculatorException(

"M

u s

ph

i khác 0!"

, ex); } } } // tạo lớp TestCalculator

class

TestCalculator

{

public static void

main

(

String

[] args) {

try

{ // tạo đối tượng Calculator

Calculator objCalc

=

new

Calculator(); // gọi phương thức divide()

objCalc

.divide(

10

,

0

); }

catch

(

CalculatorException

ex) { // lấy tham số cause từ ngoại lệ gộp

Throwable t

= ex.getCause(); // in thông báo và tham số cause

System

.out.println(

"Error: "

+ ex.getMessage());

System

.out.println(

"Cause: "

+

t

); } } }

Kết quả thực thi:

Error: Mẫu số phải khác 0!
Cause: java.lang.ArithmeticException: / by zero