Chương 4: Exceptions Chương 4: Exceptions

GVLT: Trần Anh Dũng

1

Nội dung Nội dung

2

(cid:1) Giới thiệu. (cid:1) Cách xử lý lỗi truyền thống. (cid:1) Xử lý ngoại lệ (Exception) trong java (cid:1) Ưu ñiểm của “ném” bắt ngoại lệ (cid:1) Một số lớp ngoại lệ (cid:1) Kiểm soát ngoại lệ (cid:1) Ngoại lệ do người dùng tạo (cid:1) Lan truyền ngoại lệ

Giới thiệu Giới thiệu

(cid:1) Lỗi chủ quan: do lập trình sai

(cid:1) Lỗi khách quan: do dữ liệu, do trạng thái của hệ

(cid:1) Mọi ñoạn chương trình ñều tiềm ẩn khả năng sinh lỗi

(cid:1) ?

thống (cid:1) Lỗi có 2 loại.

(cid:1) Ngoại lệ (Exception): các trường hợp hoạt ñộng không

3

bình thường

Cách xử lý lỗi truyền thống Cách xử lý lỗi truyền thống

(cid:1) Làm cho chương trình trở nên khó hiểu

(cid:1) Không phải lúc nào cũng ñầy ñủ thông tin ñể xử lý

(cid:1) Không nhất thiết phải xử lý (cid:1) Truyền trạng thái lên mức trên

(cid:1) Thông qua tham số, giá trị trả lại hoặc biến tổng thể

(cid:1) Cài ñặt mã xử lý tại nơi phát sinh ra lỗi

(cid:1) Dễ nhầm

(cid:1) Khó hiểu

4

(flag)

Ví dụ (1) Ví dụ (1)

…………

IF B IS ZERO GO TO ERROR

C = A/B

PRINT C

GO TO EXIT

ERROR:

DISPLAY “DIVISION BY ZERO”

EXIT:

END

5

Block that handles error

Ví dụ (2) Ví dụ (2)

int devide(int num, int denom, int& error)

{

if (0 != denom){

error = 0; return num/denom;

} else {

error = 1;

return 0;

}

6

}

Cách xử lý lỗi truyền thống Cách xử lý lỗi truyền thống

(cid:1) Lỗi số học

(cid:1) Lỗi bộ nhớ

(cid:1) …

(cid:1) Khó kiểm soát ñược hết các trường hợp

(cid:1) Bản chất con người

(cid:1) Thiếu kinh nghiệm, cố tình bỏ qua

7

(cid:1) Lập trình viên thường quên không xử lý lỗi

Xử lý ngoại lệ trong java Xử lý ngoại lệ trong java

(cid:1) Java là ngôn ngữ mạnh, có nghĩa là tối thiểu hóa ñược

lỗi và khi có lỗi thì chúng có thể ñược quản lý.

(cid:1) Ngoại lệ ñược “ném” tự ñộng

(cid:1) Ngoại lệ ñược “ném” tường minh

(cid:1) Ngoại lệ: là ñối tượng mang thông tin về lỗi ñã xảy ra

(cid:1) Ném ngoại

(cid:1) Dựa trên cơ chế “ném” (throw) và bắt (catch) ngoại lệ

lệ: dừng chương trình và chuyển ñiều

(cid:1) Bắt ngoại lệ: xử lý với ngoại lệ

8

khiển lên mức trên (nơi bắt ngoại lệ)

Ưu ñiểm của “ném” bắt ngoại lệ Ưu ñiểm của “ném” bắt ngoại lệ

(cid:1) Dễ dàng chuyển ñiều khiển ñến nơi có khả năng xử

(cid:1) Dễ sử dụng

(cid:1) Có thể “ném” nhiều loại ngoại lệ (cid:1) Tách xử lý ngoại lệ khỏi thuật toán

(cid:1) Tách mã xử lý

(cid:1) Sử dụng cú pháp khác

lý ngoại lệ

9

(cid:1) Không bỏ sót ngoại lệ (“ném” tự ñộng) (cid:1) Chương trình dễ ñọc hơn, an toàn hơn

Hierarchy of Exception Classes Hierarchy of Exception Classes

10

Một số lớp ngoại lệ (1) Một số lớp ngoại lệ (1)

(cid:1) Có một biến String ñể lưu thông tin chi tiết về ngoại lệ

(cid:1) Lớp Throwable

ñã xảy ra

//Tạo một ngoại lệ có tên là s.

(cid:1) Một số phương thức cơ bản (cid:2) Throwable(String s); (cid:2) String getMessage(); (cid:2) void printStackTrace(); //In ra tất cả các thông tin

//Lấy thông tin về ngoại lệ

11

liên quan ñến ngoại lệ

Một số lớp ngoại lệ (2) Một số lớp ngoại lệ (2)

(cid:1) Có nhiều ngoại lệ thuộc lớp con của Exception.

(cid:1) Người dùng có thể tạo ra các ngoại

(cid:1) Lớp Exception

lệ kế thừa từ

Exception.

(cid:1) Chỉ những lỗi nghiêm trọng và không dự ñoán trước LinkageError,

(cid:1) Lớp Error

ThreadDead, như

12

ñược VirtualMachineError…

Một số lớp ngoại lệ (3) Một số lớp ngoại lệ (3)

(cid:1) RuntimeException: Chỉ các ngoại lệ có thể xảy ra khi

(cid:1) NullPointException: con trỏ null

(cid:1) OutOfMemoryException: hết bộ nhớ

(cid:1) ArithmeticException: lỗi toán học, lỗi chia không…

(cid:1) ClassCastException: lỗi ép kiểu

(cid:1) ArrayIndexOutOfBoundsException:

JVM thực thi chương trình

lỗi vượt quá chỉ

(cid:1) ...

13

số mảng

Các loại ngoại lệ Các loại ngoại lệ

(cid:1) Java phân biệt hai loại ngoại lệ là ngoại lệ cần kiểm tra

và ngoại lệ không cần kiểm tra

(cid:1) Là các ngoại lệ không bắt buộc phải kiểm tra.

(cid:1) Gồm RuntimeException, Error và các lớp con của

(cid:1) Ngoại lệ unchecked

(cid:1) Là các ngoại lệ bắt buộc phải ñược kiểm tra.

(cid:1) Gồm các ngoại lệ còn lại.

14

chúng. (cid:1) Ngoại lệ checked

Kiểm soát ngoại lệ (1) Kiểm soát ngoại lệ (1)

(cid:1) ðoạn code có thể sinh ra lỗi cần ñặt trong khối lệnh bắt ñầu bằng try.

(cid:1) ðoạn code ñể kiểm tra, xử lý trong trường hợp có lỗi xảy ra ñặt trong khối lệnh catch.

try {

// ðoạn mã có thể sinh ra lỗi …

} catch (){

// ðoạn mã kiểm soát lỗi

15

}

Kiểm soát ngoại lệ (2) Kiểm soát ngoại lệ (2)

(cid:1) Khối lệnh ñặt trong finally luôn ñược thực thi cho dù có Exception hay không. (cid:1) Thường dùng ñể giải phóng tài nguyên

try {

// ðoạn mã có thể sinh ra lỗi …

} catch () {// ðoạn mã kiểm soát lỗi }

finally {

//ðoạn mã luôn luôn ñược thực thi

16

}

Kiểm soát ngoại lệ (3) Kiểm soát ngoại lệ (3)

try {

// Khối lệnh trước dòng lệnh sinh ra lỗi // Dòng lệnh sinh ra lỗi (Exception) //…

} catch (){

// ðoạn mã kiểm soát lỗi

Khối lệnh sau dòng lệnh sinh ra lỗi sẽ bị bỏ qua và không thực hiện khi có exception

} finally {

//…

17

}

Ví dụ (1) Kiểm soát ngoại lệ -- Ví dụ (1) Kiểm soát ngoại lệ

Ví dụ 1:

try {

int x = 10;

int y = 0;

float z = x/y;

System.out.print("Ket qua la:" + z);

} catch(ArithmeticException e) {

System.out.println(“Loi tinh toan so hoc”)

}

18

Ví dụ (2) Kiểm soát ngoại lệ -- Ví dụ (2) Kiểm soát ngoại lệ

Ví dụ 2: … void docfile(String filename) throws IOException{

… FileInputStream fin = new

FileInputStream(filename);

19

}

Ví dụ (3) Kiểm soát ngoại lệ -- Ví dụ (3) Kiểm soát ngoại lệ

Hoặc … void docfile(String filename) { …

try { …

FileInputStream fin = new

FileInputStream(filename);

… } catch (IOException e) {

System.out.println(“Loi doc file”);

}

20

}

Ví dụ (4) Kiểm soát ngoại lệ -- Ví dụ (4) Kiểm soát ngoại lệ

import java.io.*; public class MainClass {

public static void main(String[] args) {

try {

int num_1, num_2; BufferedReader in = new BufferedReader(new

InputStreamReader(System.in));

System.out.print("\n Nhap so thu 1:"); num_1 = Integer.parseInt(in.readLine()); System.out.print("\n Nhap so thu 2:"); num_2 = Integer.parseInt(in.readLine()); float rs = (float)num_1/num_2; System.out.print("\n Ket qua:" + rs);

}

21

Ví dụ (4) Kiểm soát ngoại lệ -- Ví dụ (4) Kiểm soát ngoại lệ

catch (ArithmeticException e) {

System.out.print("Loi chia cho 0");

} catch (IOException e) {

System.out.print("Loi xuat nhap");

} catch (Exception e) {

System.out.print("Loi khac");

} System.out.print(“Kiem soat duoc loi hay Khong co loi");

}

}

22

“Ném” ngoại lệ “Ném” ngoại lệ

(cid:1) Khi có lỗi phương thức sẽ ném ra một exception

(cid:1) Việc kiểm soát exception giúp chương trình kiểm soát ñược những trường hợp ngoại lệ và xử lý lỗi.

(cid:1) Dùng từ khóa throws ñể chỉ ñịnh những loại exception mà phương thức có thể “ném” ra.

throws

23

(<ñối số>) exceptions>

“Ném” ngoại lệ “Ném” ngoại lệ

(cid:1) Trong khối catch, ta có thể không xử lý trực tiếp ngoại lệ

mà lại “ném” lại ngoại lệ ñó cho nơi khác xử lý.

catch (IOException e) {

throw e;

}

24

(cid:1) Chú ý: Trong trường hợp trên, phương thức chứa catch phải bắt ngoại lệ hoặc khai báo throws cho ngoại lệ (nếu là loại checked).

“Ném” ngoại lệ khỏi phương thức “Ném” ngoại lệ khỏi phương thức

(cid:1) Không ñủ thông tin ñể xử lý

(cid:1) Không ñủ thẩm quyền

(cid:1) Không nhất thiết phải xử lý ngoại lệ trong phương thức

(cid:1) Một phương thức muốn “ném” ngoại lệ ra ngoài phải

(cid:1) Có thể “ném” ngoại lệ thuộc lớp dẫn xuất của ngoại lệ

khai báo việc “ném” ngoại lệ bằng từ khóa throws

25

ñược khai báo

Ngoại lệ do người dùng tạo (1) Ngoại lệ do người dùng tạo (1)

(cid:1) ðịnh nghĩa lớp ngoại lệ

// file MyException.java public class MyException extends Exception {

public MyException(String msg) {

super(msg);

}

26

}

Ngoại lệ do người dùng tạo (2) Ngoại lệ do người dùng tạo (2)

(cid:1) Sử dụng ngoại lệ

Khai báo khả năng ném ngoại lệ

// file ExampleException.java public class ExampleException {

public void copy(String fileName1, String fileName2)

throws MyException

{

if (fileName1.equals(fileName2)) // tung ngoại lệ throw new MyException("File trung ten"); System.out.println("Copy completed");

}

Ném ngoại lệ

27

Ngoại lệ do người dùng tạo (3) Ngoại lệ do người dùng tạo (3)

public static void main(String[] args) {

ExampleException obj=new ExampleException(); try {

String a = args[0]; String b = args[1]; obj.copy(a,b);

} catch (MyException e) {

System.out.println(e.getMessage());

}

}

28

(cid:1) Sử dụng ngoại lệ

Ngoại lệ do người dùng tạo (4) Ngoại lệ do người dùng tạo (4)

import java.io.*; // ArrayCatch.java class MyException extends ArrayIndexOutOfBoundsException{

MyException(){

super("\nChi so nam ngoai pham vi cua mang");

}

} class ArrayCatch{

int a[]= { 1,2,3,4,5}; int n=5; public static void main(String args[]){

ArrayCatch Obj= new ArrayCatch(); Obj.OutElement(7);

} void OutElement(int i) throws MyException{

if (i<0 || i>=n) throw new MyException(); else System.out.println (a[i]);

}

}

29

Lan truyền ngoại lệ Lan truyền ngoại lệ

(cid:1) Giả sử trong main() gọi phương thức A(), trong A() gọi B(), trong B() gọi C(). Khi ñó một ngăn xếp các phương thức ñược tạo ra.

(cid:1) Giả sử trong C() xảy ra ngoại lệ.

C() tung ngoại lệ

C()

B()

B()

A()

A()

main()

main()

30

(cid:1) Tình huống:

Thừa kế và vấn ñề bắt ngoại lệ Thừa kế và vấn ñề bắt ngoại lệ

try{

try{

//…

//…

} catch (EOFException e){

} catch (IOException e){

//…

//…

} catch (IOException e){

} catch (EOFException e){

//…

//…

}

}

31

ðúng Sai

Bài tập Bài tập

1. Viết chương trình cho phép tính giá trị của biểu thức:

5x - y

A =

2x + 7y

Yêu cầu xử lý các ngoại lệ có thể xảy ra.

32

2. Viết chương trình cho phép tạo một mảng 2 chiều cỡ mxn với m, n nhập từ bàn phím. Cài ñặt các xử lý ngoại lệ cần thiết.

Bài tập Bài tập

3. Xây dựng lớp ngoại lệ DateException cho các lỗi về

ngày tháng.

33

4. Viết chương trình cho phép người dùng nhập vào ngày, tháng năm, nếu thông tin này không hợp lệ sẽ tung ra một ngoại lệ DateException, sau ñó thông báo cho người nhập biết và cho phép người dùng nhập lại.

Hỏi & ñáp Hỏi & ñáp

34