Professional Documents
Culture Documents
Bai 10 - Ngoai Le Va Xu Ly Ngoai Le
Bai 10 - Ngoai Le Va Xu Ly Ngoai Le
1 2
1 2
3 4
3 4
1
1.1. Ngoại lệ là gì? 1.1. Ngoại lệ là gì? (2)
v Exception = Exceptional event v Ngoại lệ là một lỗi đặc biệt
v Định nghĩa: Ngoại lệ là một sự kiện xảy ra v Khi xảy ra một ngoại lệ, nếu không xử lý thì
trong quá trình thực thi chương trình, nó phá chương trình kết thúc ngay và trả lại quyền điều
vỡ luồng bình thường của chương trình khiển cho hệ điều hành.
ERROR !!
Ví dụ:
5 6
5 6
7 8
7 8
2
Nhược điểm Nội dung
v Khó kiểm soát được hết các trường hợp 1. Ngoại lệ
§ Lỗi số học, lỗi bộ nhớ,…
v Lập trình viên thường quên không xử lý lỗi
2. Bắt và xử lý ngoại lệ
§ Bản chất con người 3. Ủy nhiệm ngoại lệ
§ Thiếu kinh nghiệm, cố ?nh bỏ qua 4. Tạo ngoại lệ tự định nghĩa
9 10
9 10
2.1. Mục đích của xử lý ngoại lệ 2.1. Mục đích của xử lý ngoại lệ (2)
v Giúp chương trình đáng ,n cậy hơn, tránh kết thúc bất v Khi xảy ra ngoại lệ, nếu không có cơ chế xử lý thích
thường hợp:
v Tách biệt khối lệnh có thể gây ngoại lệ và khối lệnh § Chương trình bị ngắt khi ngoại lệ xảy ra
xử lý ngoại lệ § Các tài nguyên không được giải phóng à Lãng phí
…………
v Ví dụ: Vào/ra tệp gn
IF B IS ZERO GO TO ERROR
§ Nếu ngoại lệ xảy ra (ví dụ như chuyển đổi kiểu không đúng)
C = A/B à Chương trình kết thúc mà không đóng tệp >n lại
PRINT C • Tệp %n không thể truy cập/hỏng
GO TO EXIT • Tài nguyên cấp phát không được giải phóng
EXIT:
END 12
11 12
3
2.2. Mô hình xử lý ngoại lệ 2.2. Mô hình xử lý ngoại lệ (2)
v Hướng đối tượng v Ngoại lệ cần phải được xử lý ở tại phương thức
§ Đóng gói các điều kiện không mong đợi trong một đối sinh ra ngoại lệ hoặc ủy nhiệm cho phương thức
tượng gọi đến
§ Khi xảy ra ngoại lệ, đối tượng tương ứng với ngoại lệ
được tạo ra chứa thông ,n chi ,ết về ngoại lệ
§ Cung cấp cơ chế hiệu quả trong việc xử lý lỗi
§ Tách biệt luồng điều khiển bất thường với luồng bình
thường
13 14
13 14
15 16
15 16
4
2.3.1. Khối try/catch Ví dụ không xử lý ngoại lệ
v Khối try ... catch: Phân tách đoạn chương trình class NoException {
thông thường và phần xử lý ngoại lệ public static void main(String args[])
{
§ try {…}: Khối lệnh có khả năng gây ra ngoại lệ
String text = args[0];
§ catch() {…}: Bắt và xử lý với ngoại lệ
System.out.println(text);
try {
}
// Doan ma co the gay ngoai le }
} catch (ExceptionType e) {
// Xu ly ngoai le
}
v ExceptionType là một lớp con của Throwable
17 18
17 18
19 20
19 20
5
2.3.2. Cây phân cấp ngoại lệ trong Java a. Lớp Throwable
v Một biến kiểu String để lưu thông gn chi gết về
Error chỉ ra các lỗi đặc
biệt nghiêm trọng, những Throwable là một lớp
ngoại lệ đã xảy ra
lỗi này chương trình Exception
cơ sở, nó
cho tấtdiện
là cung
cả các
lớp cơcấp
sở v Một số phương thức cơ bản
không thể quản lý được.
Object giao vàlỗi
sựcó thể
thực
VD: VirtualMachineError kiểm
thi chosoát
hầuđược.
hết các
§ new Throwable(String s): Tạo một ngoại lệ
OutOfMemoryError VD: ArithmeticException,
ngoại lệ. với thông tin về ngoại lệ là s
Throwable BufferOverflowException
§ String getMessage(): Lấy thông ,n về ngoại lệ
§ void printStackTrace(): In ra tất cả các thông
Error Exception ,n liên quan đến ngoại lệ (tên, loại, vị trí...)
§ …
... RuntimeException
...
...
21 22
21 22
b. Lớp Error
public class StckExceptionDemo {
public static void main(String args[]){ v Gồm các ngoại lệ nghiêm trọng không thể kiểm tra
try { (unchecked excep=on) vì có thể xảy ra ở nhiều phần
int num = calculate(9,0); của chương trình.
System.out.println(num);
}
v Còn gọi là ngoại lệ không thể phục hồi (un-recoverable
catch(Exception e) {
excep=on)
System.err.println(“Co loi xay ra :" v Không cần kiểm tra trong mã nguồn Java của bạn
+ e.getMessage()); v Các lớp con:
e.printStackTrace();
§ VirtualMachineError: InternalError, OutOfMemoryError,
} StackOverflowError, UnknownError
} § ThreadDeath
static int calculate(int no, int no1) { § LinkageError:
int num = no / no1; • Incompa(bleClassChangeError
return num; • AbstractMethodError, Instan(a(onError, NoSuchFieldError,
} NoSuchMethodError…
• …
}
§ …
23
23 24
6
c. Lớp Exception Một số lớp con của Exception
v ClassNotFoundExcepOon, SQLExcepOon
v Chứa các loại ngoại lệ
nên/phải bắt và xử lý hoặc ủy v java.io.IOExcepOon:
nhiệm. § FileNotFoundExcep>on, EOFExcep>on…
v Người dùng có thể tạo ra các v RunOmeExcepOon:
ngoại lệ của riêng mình bằng § NullPointerExcep>on, BufferOverflowExcep>on
cách kế thừa từ ExcepOon § ClassCastExcep>on, Arithme>cExcep>on
v RunOmeExcepOon có thể được § IndexOutOfBoundsExcep>on:
“tung” ra trong quá trình JVM • ArrayIndexOutOfBoundsExcep%on,
thực hiện • StringIndexOutOfBoundsExcep%on…
§ Không bắt buộc phải bắt ngoại lệ § IllegalArgumentExcep>on:
dù có thể xảy ra lỗi • NumberFormatExcep%on, InvalidParameterExcep%on…
§ Không nên viết ngoại lệ của riêng § …
mình kế thừa từ lớp này
25 26
25 26
27 28
27 28
7
2.3.4. Nhiều khối catch
vExceptionType1 phải là lớp con hoặc ngang hàng
v Một đoạn mã có thể gây ra nhiều hơn một ngoại với ExceptionType2 (trong cây phân cấp kế thừa)
lệ à Sử dụng nhiều khối catch. class MultipleCatch1 {
try { public static void main(String args[])
// Doan ma co the gay ra nhieu ngoai le {
try {
} catch (ExceptionType1 e1) { String num = args[0];
// Xu ly ngoai le 1 int numValue = Integer.parseInt(num);
System.out.println("Dien tich hv la: "
} catch (ExceptionType2 e2) { + numValue * numValue);
// Xu ly ngoai le 2 } catch(Exception e1) {
System.out.println("Hay nhap canh cua hv!");
} ...
} catch(NumberFormatException e2){
v ExceptionType1 phải là lớp con hoặc ngang System.out.println("Not a number!");
hàng với ExceptionType2 (trong cây phân cấp }
kế thừa) }
D:\exception java.lang.NumberFormatException has already been
} Lỗi caught
29 30
29 30
class MultiCatch2 {
vExceptionType1 phải là lớp con hoặc ngang hàng public static void main( String args[]) {
với ExceptionType2 (trong cây phân cấp kế thừa) try {
class MultipleCatch1 { // format a number
public static void main(String args[]) // read a file
{ // something else...
try { }
catch(IOException e) {
String num = args[0];
System.out.println("I/O error "+e.getMessage();
int numValue = Integer.parseInt(num);
}
System.out.println("Dien tich hv la: "
catch(NumberFormatException e) {
+ numValue * numValue); System.out.println("Bad data "+e.getMessage();
} catch(ArrayIndexOutOfBoundsException e1) { }
System.out.println(“Hay nhap canh cua hv!"); catch(Throwable e) { // catch all
} catch(NumberFormatException e2){ System.out.println("error: " + e.getMessage();}
System.out.println(“Hay nhap 1 so!"); }
} }
} }
31 32
}
31 32
8
... 2.3.5. Khối finally
public void openFile(){
try { v Đảm bảo thực hiện tất cả các công việc cần
// constructor may throw FileNotFoundException thiết khi có ngoại lệ xảy ra
FileReader reader = new FileReader("someFile"); § Đóng file, đóng socket, connection
int i=0; § Giải phóng tài nguyên (nếu cần)...
while(i != -1) {
//reader.read() may throw IOException v Chắc chắn sẽ thực hiện dù ngoại lệ có xảy ra hay
i = reader.read(); không.
System.out.println((char) i );
}
reader.close(); No exception
finally
System.out.println("--- File End ---");
} catch (FileNotFoundException e) {
//do something clever with the exception try block
} catch (IOException e) { catch block finally
//do something clever with the exception Exception
}
}
... 33 34
33 34
35 36
9
public void openFile(){
Nội dung
try {
// constructor may throw FileNotFoundException 1. Ngoại lệ
FileReader reader = new FileReader("someFile");
int i=0; 2. Bắt và xử lý ngoại lệ
while(i != -1) {
//reader.read() may throw IOException
i = reader.read();
3. Ủy nhiệm ngoại lệ
}
System.out.println((char) i );
4. Tạo ngoại lệ tự định nghĩa
} catch (FileNotFoundException e) {
//do something clever with the exception
} catch (IOException e) {
//do something clever with the exception
} finally {
reader.close();
System.out.println("--- File End ---");
}
}
37 38
37 38
39 40
39 40
10
3.1. Ủy nhiệm ngoại lệ (2) 3.1. Ủy nhiệm ngoại lệ (3)
v Nếu phương thức có chứa câu lệnh tung v Phương thức không cần phải khai báo sẽ tung ra
ngoại lệ (throw) thì phần khai báo phương RunOmeExcepOon vì ngoại lệ này mặc định được
thức phải khai báo là có tung ngoại lệ đó hoặc ủy nhiệm cho JVM
lớp cha của ngoại lệ đó v Ví dụ
class Test {
public void myMethod(int param) {
public void myMethod(int param) {
if (param < 10) { if (param < 10) {
throw new Exception("Too low!"); throw new RuntimeException("Too
} low!");
}
//Blah, Blah, Blah...
//Blah, Blah, Blah...
} }
à unreported excep,on java.lang.Excep,on; must be }
caught or declared to be thrown § à Không lỗi
41 42
41 42
Run
return num;
}
}
43 44
43 44
11
public class DelegateExceptionDemo {
public static void main(String args[]){ public class DelegateExceptionDemo {
int num = calculate(9,3); public static void main(String args[]){
System.out.println(“Lan 1: ” + num); try {
num = calculate(9,0); int num = calculate(9,3);
System.out.println(“Lan 2: ” + num); System.out.println(“Lan 1: ” + num);
} num = calculate(9,0);
static int calculate(int no, int no1) System.out.println(“Lan 2: ” + num);
throws Exception { } catch(Exception e) {
System.out.println(e.getMessage());
if (no1 == 0)
}
throw new
}
ArithmeticException("Khong the chia cho 0!");
static int calculate(int no, int no1)
Compile
int num = no / no1;
throws ArithmeticException {
return num; if (no1 == 0)
} throw new
} ArithmeticException("Khong the chia cho 0!");
G:\Java Example\DelegateExceptionDemo.java:3: unreported exception java.lang.Exception;
must be caught or declared to be thrown
int num = no / no1;
int num = calculate(9,3); return num;
^ }
G:\Java Example\DelegateExceptionDemo.java:5: unreported exception java.lang.Exception; }
must be caught or declared to be thrown 45 46
num = calculate(9,0);
45 46
47 48
47 48
12
3.2. Lan truyền ngoại lệ (2) 3.3. Kế thừa và ủy nhiệm ngoại lệ
C()
C() tung ngoại lệ v Khi override một phương thức của lớp cha,
B()
phương thức ở lớp con không được phép tung ra
B()
A()
các ngoại lệ mới
A()
main()
main()
v à Phương thức ghi đè trong lớp con chỉ được
v Nếu C() gặp lỗi và tung ra ngoại lệ nhưng trong C() lại không phép tung ra các ngoại lệ giống hoặc là lớp con
xử lý ngoại lệ này, thì chỉ còn một nơi có thể xử lý chính là hoặc là tập con của các ngoại lệ được tung ra
nơi mà C() được gọi, đó là trong phương thức B(). ở lớp cha.
v Nếu trong B() cũng không xử lý thì phải xử lý ngoại lệ này
trong A()… Quá trình này gọi là lan truyền ngoại lệ
v Nếu đến main() cũng không xử lý ngoại lệ được tung từ C()
thì chương trình sẽ phải dừng lại.
49 50
49 50
3.3. Kế thừa và ủy nhiệm ngoại lệ (2) 3.4. Ưu điểm của ủy nhiệm ngoại lệ
class Disk { v Dễ sử dụng
void readFile() throws EOFException {} § Làm chương trình dễ đọc và an toàn hơn
} § Dễ dàng chuyển điều khiển đến nơi có khả năng xử lý
class FloppyDisk extends Disk { ngoại lệ
void readFile() throws IOException {} // ERROR! § Có thể ném nhiều loại ngoại lệ
} v Tách xử lý ngoại lệ khỏi đoạn mã thông thường
v Không bỏ sót ngoại lệ (ném tự động)
class Disk { v Gom nhóm và phân loại các ngoại lệ
void readFile() throws IOException {}
}
v KL: Làm chương trình dễ đọc và an toàn hơn
class FloppyDisk extends Disk {
void readFile() throws EOFException {} //OK
}
51 52
51 52
13
Nội dung 4. Tạo ngoại lệ tự định nghĩa
1. Ngoại lệ v Các ngoại lệ do hệ thống xây dựng không đủ để kiểm
soát tất cả các lỗi à Cần phải có các lớp ngoại lệ do
2. Bắt và xử lý ngoại lệ người dùng định nghĩa.
§ Kế thừa từ một lớp Exception hoặc lớp con của nó
3. Ủy nhiệm ngoại lệ § Có tất cả các phương thức của lớp Throwable
public class MyException extends Exception {
4. Tạo ngoại lệ tự định nghĩa public MyException(String msg) {
super(msg);
}
public MyException(String msg, Throwable cause){
super(msg, cause);
}
}
53 54
53 54
Sử dụng ngoại lệ người dùng định nghĩa Sử dụng ngoại lệ người dùng định nghĩa
55 56
14
Tổng kết Tổng kết (2)
v Bất cứ khi nào có một lỗi xảy ra khi thực hiện v Các câu lệnh trong khối try tung ra ngoại lệ, và
chương trình thì một ngoại lệ đã xuất hiện. việc xử lý các ngoại lệ đó diễn ra trong khối catch.
v Mọi ngoại lệ đề phải được xử lý nếu không muốn v Nhiều khối catch có thể được sử dụng để xử lý
chương trình kết thúc một cách bất thường. tách biệt các loại ngoại lệ khác nhau.
v Xử lý ngoại lệ cho phép kết hợp và xử lý lỗi tại một v Từ khóa throws được sử dụng để liệt kê mỗi danh
nơi. sách các ngoại lệ mà một phương thức có thể
v Java sử dụng khối try/catch để quản lý ngoại lệ. tung ra.
v Từ khóa throw được sử dụng để tung ra một ngoại
lệ.
v Khối finally để thực hiện các công việc cần thiết dù
có ngoại lệ xảy ra hay không.
57 58
57 58
Bài tập 1
v Hệ thống liên tục nhận các giá trị đầu vào là xâu đại
diện cho một số nguyên, yêu cầu mỗi lần nhận được
một số thì tính trung bình cộng của các giá trị đã
nhận.
v Xây dựng phương thức:
59 60 60
59 60
15
Bài tập 2 Bài tập 3
v Hệ thống cần đọc file để lấy ra một dãy các con số v Hệ thống cần đọc file đầu vào để lấy ra một dãy các
(mỗi dòng một số nguyên) con số (mỗi dòng một số nguyên), sau đó tách ra
§ Dòng 1 của file là số lượng các số có trong file thành 4 phần bằng nhau và ghi ra các file khác nhau.
§ Mỗi dòng là một số nguyên § Dòng 1 của file đầu vào là số lượng các số có trong file. Mỗi
dòng sau đó là một số nguyên
v Xây dựng phương thức đọc dãy số:
§ Xây dựng phương thức phân tách dãy số:
§ public void readListIntegers(String fileName) • public void splitListIntegers(String fileName)
v Hãy xử lý các ngoại lệ: v Hãy xử lý các ngoại lệ:
§ Xâu tên file là xâu rỗng § Xâu tên file là xâu rỗng
§ Không tìm thấy file § Không tìm thấy file
§ Không mở được file § Không mở được file
§ Các xâu trong từng dòng của file không phải là đại diện cho
§ Các xâu trong từng dòng của file không phải là đại diện cho
con số con số
§ Không ghi được file mới
61 61 62 62
61 62
16