Xem mẫu
- 9/18/17
Mục tiêu của bài học
Bộ môn Công nghệ Phần mềm n Giải thích về ngoại lệ là gì và mô tả các lợi
Viện CNTT & TT ích của việc xử lý ngoại lệ hướng đối tượng
Trường Đại học Bách Khoa Hà Nội n Giải thích được mô hình xử lý ngoại lệ
n Sử dụng khối try/catch/finally để bắt và xử lý
ngoại lệ trong Java
LẬP TRÌNH HƯỚNG ĐỐI TƯỢNG n Hiểu và biết cách sử dụng ủy nhiệm ngoại lệ
Bài 08. Ngoại lệ và xử lý ngoại lệ n Biết cách tạo ra và sử dụng ngoại lệ tự định
nghĩa
2
Nội dung Nội dung
1. Ngoại lệ 1. Ngoại lệ
2. Bắt và xử lý ngoại lệ 2. Bắt và xử lý ngoại lệ
3. Ủy nhiệm ngoại lệ 3. Ủy nhiệm ngoại lệ
4. Tạo ngoại lệ tự định nghĩa 4. Tạo ngoại lệ tự định nghĩa
3 4
1
- 9/18/17
1.1. Ngoại lệ là gì? 1.1. Ngoại lệ là gì? (2)
n Exception = Exceptional event n Ngoại lệ là một lỗi đặc biệt
n Định nghĩa: Ngoại lệ là một sự kiện xảy ra n 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
vỡ luồng bình thường của chương trình điều khiển cho hệ điều hành.
ERROR !!
Ví dụ:
5 6
1.2. Cách xử lý lỗi truyền thống Ví dụ
int devide(int num, int denom, int *error)
n Viết mã xử lý tại nơi phát sinh ra lỗi
{
n Làm cho chương trình trở nên rối
if (denom != 0){
n Không phải lúc nào cũng đầy đủ thông tin để xử error = 0;
lý return num/denom;
n Không nhất thiết phải xử lý } else {
n Truyền trạng thái lên mức trên error = 1;
n Thông qua tham số, giá trị trả lại hoặc biến tổng return 0;
thể (flag) }
n Dễ nhầm }
n Vẫn còn khó hiểu 7 8
2
- 9/18/17
Nhược điểm Nội dung
n Khó kiểm soát được hết các trường hợp 1. Ngoại lệ
n Lỗi số học, lỗi bộ nhớ,…
2. Bắt và xử lý ngoại lệ
n Lập trình viên thường quên không xử lý lỗi
n Bản chất con người
3. Ủy nhiệm ngoại lệ
n Thiếu kinh nghiệm, cố tình bỏ qua 4. Tạo ngoại lệ tự định nghĩa
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)
n Giúp chương trình đáng tin cậy hơn, tránh n Khi xảy ra ngoại lệ, nếu không có cơ chế xử
kết thúc bất thường
lý thích hợp:
n Tách biệt khối lệnh có thể gây ngoại lệ và
khối lệnh xử lý ngoại lệ n Chương trình bị ngắt khi ngoại lệ xảy ra
………… n Các tài nguyên không được giải phóng à Lãng
IF B IS ZERO GO TO ERROR
C = A/B phí
PRINT C
GO TO EXIT n Ví dụ: Vào/ra tệp tin
n Nếu ngoại lệ xảy ra (ví dụ như chuyển đổi kiểu
ERROR: Khối xử lý lỗi
DISPLAY “DIVISION BY ZERO” không đúng) à Chương trình kết thúc mà không
đóng tệp tin lại
EXIT:
END n Tệp tin không thể truy cập/hỏng
11
n Tài nguyên cấp phát không được giải phóng 12
3
- 9/18/17
2.2. Mô hình xử lý ngoại lệ 2.2. Mô hình xử lý ngoại lệ (2)
n Hướng đối tượng n Ngoại lệ cần phải được xử lý ở tại phương
n Đóng gói các điều kiện không mong đợi trong một đối thức sinh ra ngoại lệ hoặc ủy nhiệm cho
tượng
phương thức gọi đến
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 tin chi tiết về ngoại lệ
n Cung cấp cơ chế hiệu quả trong việc xử lý lỗi
n Tách biệt luồng điều khiển bất thường với luồng bình
thường
13 14
2.3. Xử lý ngoại lệ trong Java 2.3. Xử lý ngoại lệ trong Java (2)
n Java có cơ chế xử lý ngoại lệ rất n Các từ khóa
mạnh
n Xử lý ngoại lệ trong Java được
n try
thực hiện theo mô hình hướng đối n catch
tượng:
n finally
n Tất cả các ngoại lệ đều là thể hiện
của một lớp kế thừa từ lớp Throwable n throw
hoặc các lớp con của nó
n Các đối tượng này có nhiệm vụ n throws
chuyển thông tin về ngoại lệ (loại và
trạng thái của chương trình) từ vị trí
xảy ra ngoại lệ đến nơi quản lý/xử lý
nó.
15 16
4
- 9/18/17
2.3.1. Khối try/catch Ví dụ không xử lý ngoại lệ
n Khối try ... catch: Phân tách đoạn chương class NoException {
public static void main(String args[]) {
trình thông thường và phần xử lý ngoại lệ
String text = args[0];
n try {…}: Khối lệnh có khả năng gây ra ngoại lệ
System.out.println(text);
n catch() {…}: Bắt và xử lý với ngoại lệ
}
try {
}
// Doan ma co the gay ngoai le
}
catch (ExceptionType e) {
// Xu ly ngoai le
}
n ExceptionType là một lớp con của Throwable 17 18
Ví dụ có xử lý ngoại lệ Ví dụ chia cho 0
public class ChiaCho0Demo {
public static void main(String args[]){
class ArgExceptionDemo {
try {
public static void main(String args[]) {
int num = calculate(9,0);
try {
System.out.println(num);
String text = args[0];
}
System.out.println(text);
catch(Exception e) {
}
catch(Exception e) { System.err.println("Co loi xay ra: " + e.toString());
System.out.println(“Hay nhap tham so khi chay!"); }
} }
} static int calculate(int no, int no1){
} int num = no / no1;
return num;
}
}
19 20
5
- 9/18/17
2.3.2. Cây phân cấp ngoại lệ trong Java a. Lớp Throwable
Error chỉ ra các lỗi đặc n Một biến kiểu String để lưu thông tin chi tiết về
biệt nghiêm trọng, những
lỗi này chương trình
Throwable là một lớp
Exception là cung
lớp cơcấp
sở
ngoại lệ đã xảy ra
cơ sở, nó
không thể quản lý được.
Object
cho tấtdiện
giao
kiểm
cả các
vàlỗi
sựcó thể
thực n Một số phương thức cơ bản
VD: VirtualMachineError thi chosoát
hầuđược.
hết các
OutOfMemoryError VD: ArithmeticException,
ngoại lệ. n new Throwable(String s): Tạo một ngoại lệ với
BufferOverflowException
Throwable thông tin về ngoại lệ là s
n String getMessage(): Lấy thông tin về ngoại lệ
Error Exception n String getString(): Mô tả ngắn gọn về ngoại lệ
n void printStackTrace(): In ra tất cả các thông tin
RuntimeException liên quan đến ngoại lệ (tên, loại, vị trí...)
...
... n …
...
21 22
public class StckExceptionDemo { b. Lớp Error
public static void main(String args[]){
try {
int num = calculate(9,0); n Gồm các ngoại lệ nghiêm trọng không thể kiểm tra
System.out.println(num); (unchecked exception) vì có thể xảy ra ở nhiều phần của
} chương trình.
catch(Exception e) { n Còn gọi là ngoại lệ không thể phục hồi (un-recoverable
System.err.println(“Co loi xay ra :" exception)
+ e.getMessage());
n Không cần kiểm tra trong mã nguồn Java của bạn
e.printStackTrace();
} n Các lớp con:
} n VirtualMachineError: InternalError, OutOfMemoryError,
static int calculate(int no, int no1) { StackOverflowError, UnknownError
int num = no / no1; n ThreadDeath
return num; n LinkageError:
} n IncompatibleClassChangeError
} n AbstractMethodError, InstantiationError, NoSuchFieldError,
NoSuchMethodError…
n …
n …
23 24
6
- 9/18/17
c. Lớp Exception Một số lớp con của Exception
n Chứa các loại ngoại lệ n ClassNotFoundException, SQLException
nên/phải bắt và xử lý hoặc ủy n java.io.IOException:
nhiệm. n FileNotFoundException, EOFException…
n Người dùng có thể tạo ra các n RuntimeException:
ngoại lệ của riêng mình bằng
NullPointerException, BufferOverflowException
cách kế thừa từ Exception n
n ClassCastException, ArithmeticException
n RuntimeException có thể IndexOutOfBoundsException:
được “tung” ra trong quá
n
ArrayIndexOutOfBoundsException,
trình JVM thực hiện
n
n StringIndexOutOfBoundsException…
n Không bắt buộc phải bắt ngoại n IllegalArgumentException:
lệ dù có thể xảy ra lỗi n NumberFormatException, InvalidParameterException…
n Không nên viết ngoại lệ của …
riêng mình kế thừa từ lớp này
n
25 26
Ví dụ IOException 2.3.3. Khối try – catch lồng nhau
import java.io.InputStreamReader;
import java.io.IOException; n Những phần nhỏ trong khối mã sinh ra một lỗi,
public class HelloWorld{ nhưng toàn bộ cả khối thì lại sinh ra một lỗi
public static void main(String[] args) {
khác à Cần có các xử lý ngoại lệ lồng nhau.
InputStreamReader isr = new n Khi các khối try lồng nhau, khối try bên trong sẽ
InputStreamReader(System.in); được thực hiện trước.
try {
System.out.print("Nhap vao 1 ky tu: "); try {
// Doan ma co the gay ra IOException
char c = (char) isr.read(); try {
System.out.println("Ky tu vua nhap: " + c); // Doan ma co the gay ra NumberFormatException }
catch (NumberFormatException e1) {
}catch(IOException ioe) { // Xu ly loi sai dinh dang so
ioe.printStackTrace(); }
} catch (IOException e2) {
} // Xu ly loi vao ra
} }
27 28
}
7
- 9/18/17
2.3.4. Nhiều khối catch n ExceptionType1 phải là lớp con hoặc ngang hàng v
ới ExceptionType2 (trong cây phân cấp kế thừa)
n Một đoạn mã có thể gây ra nhiều hơn một ngoại lệ à class MultipleCatch1 {
Sử dụng nhiều khối catch. public static void main(String args[])
{
try { try {
// Doan ma co the gay ra nhieu ngoai le String num = args[0];
} catch (ExceptionType1 e1) { int numValue = Integer.parseInt(num);
System.out.println("Dien tich hv la: "
// Xu ly ngoai le 1 + numValue * numValue);
} catch (ExceptionType2 e2) { } catch(Exception e1) {
// Xu ly ngoai le 2 System.out.println("Hay nhap canh cua hv!");
} catch(NumberFormatException e2){
} ... System.out.println("Not a number!");
n ExceptionType1 phải là lớp con hoặc ngang 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
class MultiCatch2 {
n ExceptionType1 phải là lớp con hoặc ngang public static void main( String args[]) {
hàng với ExceptionType2 (trong cây phân cấ try {
p kế thừa) // format a number
// read a file
class MultipleCatch1 {
// something else...
public static void main(String args[])
{ }
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(NumberFormatException e2){ catch(Throwable e) { // catch all
System.out.println(“Hay nhap 1 so!"); System.out.println("error: " + e.getMessage();}
} }
} }
31 32
} }
8
- 9/18/17
...
public void openFile(){
2.3.5. Khối finally
try {
// constructor may throw FileNotFoundException
FileReader reader = new FileReader("someFile"); n Đảm bảo thực hiện tất cả các công việc cần
int i=0;
while(i != -1) {
thiết khi có ngoại lệ xảy ra
//reader.read() may throw IOException n Đóng file, đóng socket, connection
i = reader.read();
System.out.println((char) i ); n Giải phóng tài nguyên (nếu cần)...
}
reader.close(); n Chắc chắn sẽ thực hiện dù ngoại lệ có xảy ra
System.out.println("--- File End ---");
} catch (FileNotFoundException e) {
hay không.
No exception finally
//do something clever with the exception
} catch (IOException e) {
//do something clever with the exception try block
}
} catch block finally
... Exception
33 34
Cú pháp try ... catch ... finally class StrExceptionDemo {
static String str;
public static void main(String s[]) {
try { try {
// Khoi lenh co the sinh ngoai le System.out.println(“Truoc ngoai le");
staticLengthmethod();
}
System.out.println(“Sau ngoai le");
catch(ExceptionType e) { }
// Bat va xu ly ngoai le catch(NullPointerException ne) {
} System.out.println(“Da xay ra loi");
finally { }
finally {
/* Thuc hien cac cong viec can thiet du
ngoai le co xay ra hay khong */ System.out.println(“Trong finally");
}
} }
n Nếu đã có khối try thì bắt buộc phải có khối
catch hoặc khối finally hoặc cả hai static void staticLengthmethod() {
System.out.println(str.length());
}
35 } 36
9
- 9/18/17
public void openFile(){ Nội dung
try {
// constructor may throw FileNotFoundException
Ngoại lệ
FileReader reader = new FileReader("someFile");
int i=0; 1.
while(i != -1) {
//reader.read() may throw IOException
i = reader.read();
2. Bắt và xử lý ngoại lệ
}
System.out.println((char) i );
3. Ủy nhiệm ngoại lệ
} catch (FileNotFoundException e) {
//do something clever with the exception 4. Tạo ngoại lệ tự định nghĩa
} catch (IOException e) {
//do something clever with the exception
} finally {
reader.close();
System.out.println("--- File End ---");
}
}
37 38
Hai cách làm việc với ngoại lệ 3.1. Ủy nhiệm ngoại lệ
n Xử lý ngay n Phương thức có thể ủy nhiệm ngoại lệ cho vị trí gọi nó bằ
ng cách:
n Sử dụng khối try ... catch (finally nếu cần). n Sử dụng throws ExceptionType ở phần khai báo phương thức
n Ủy nhiệm cho vị trí gọi nó: để báo hiệu cho vị trí gọi nó biết là nó có thể phát sinh ngoại l
ệ ExceptionType
n Nếu không muốn xử lý ngay n Sử dụng throw để tung ra ngoại lệ kiểu ExceptionType trong
thân phương thức khi cần
n Sử dụng throw và throws
n Ví dụ
public void myMethod(int param) throws Exception{
if (param < 10) {
throw new Exception("Too low!");
}
//Blah, Blah, Blah...
}
39 40
10
- 9/18/17
3.1. Ủy nhiệm ngoại lệ (2) 3.1. Ủy nhiệm ngoại lệ (3)
n Nếu phương thức có chứa câu lệnh tung ngo n Phương thức không cần phải khai báo sẽ tung ra
RuntimeException vì ngoại lệ này mặc định được ủy
ại lệ (throw) thì phần khai báo phương thức nhiệm cho JVM
phải khai báo là có tung ngoại lệ đó hoặc lớp n Ví dụ
cha của ngoại lệ đó class Test {
public void myMethod(int param) {
public void myMethod(int param) { if (param < 10) {
if (param < 10) { throw new RuntimeException("Too low!");
throw new Exception("Too low!"); }
} //Blah, Blah, Blah...
//Blah, Blah, Blah... }
} }
à unreported exception java.lang.Exception; must be n à Không lỗi
caught or declared to be thrown
41 42
3.1. Ủy nhiệm ngoại lệ (3) public class DelegateExceptionDemo {
public static void main(String args[]){
int num = calculate(9,3);
n Tại vị trí gọi phương thức có ủy nhiệm ngoại System.out.println(“Lan 1: ” + num);
num = calculate(9,0);
lệ (trừ RuntimeException): System.out.println(“Lan 2: ” + num);
}
n Hoặc là phương thức chứa vị trí đó phải ủy nhiệ static int calculate(int no, int no1)
m tiếp cho vị trí gọi mình throws ArithmeticException {
if (no1 == 0)
n Hoặc là tại ví trí gọi phải bắt ngoại lệ ủy nhiệm throw new
(hoặc lớp cha) và xử lý ngay bằng try...catch ArithmeticException("Khong the chia cho 0!");
int num = no / no1;
(finally nếu cần) return num;
}
Run
}
43 44
11
- 9/18/17
public class DelegateExceptionDemo {
public static void main(String args[]){
int num = calculate(9,3); public class DelegateExceptionDemo {
System.out.println(“Lan 1: ” + num); public static void main(String args[]){
num = calculate(9,0); try {
System.out.println(“Lan 2: ” + num); int num = calculate(9,3);
} System.out.println(“Lan 1: ” + num);
static int calculate(int no, int no1) num = calculate(9,0);
throws Exception { System.out.println(“Lan 2: ” + num);
if (no1 == 0) } catch(Exception e) {
throw new System.out.println(e.getMessage());
ArithmeticException("Khong the chia cho 0!"); }
int num = no / no1; }
Compile
return num; static int calculate(int no, int no1)
} throws ArithmeticException {
} if (no1 == 0)
G:\Java Example\DelegateExceptionDemo.java:3: unreported exception java.lang.Exception; throw new
must be caught or declared to be thrown ArithmeticException("Khong the chia cho 0!");
int num = calculate(9,3); int num = no / no1;
^
return num;
G:\Java Example\DelegateExceptionDemo.java:5: unreported exception java.lang.Exception;
must be caught or declared to be thrown }
num = calculate(9,0); 45 } 46
3.1. Ủy nhiệm ngoại lệ (4) 3.2. Lan truyền ngoại lệ
n Một phương thức có thể ủy nhiệm nhiều hơn n Tình huống:
1 ngoại lệ
public void myMethod(int tuoi, String ten) n Giả sử trong main() gọi phương thức A(), trong
throws ArithmeticException, NullPointerException{ A() gọi B(), trong B() gọi C(). Khi đó một ngăn
if (tuoi < 18) { xếp các phương thức được tạo ra.
throw new ArithmeticException(“Chua du tuoi!");
} n Giả sử trong C() xảy ra ngoại lệ.
if (ten == null) {
throw new NullPointerException(“Thieu ten!");
}
//Blah, Blah, Blah...
}
47 48
12
- 9/18/17
3.2. Lan truyền ngoại lệ (2) 3.3. Kế thừa và ủy nhiệm ngoại lệ
C() tung ngoại lệ
C() n Khi override một phương thức của lớp cha,
B() B()
phương thức ở lớp con không được phép
A()
main()
A()
tung ra các ngoại lệ mới
main()
n Nếu C() gặp lỗi và tung ra ngoại lệ nhưng trong C() lại không xử
lý ngoại lệ này, thì chỉ còn một nơi có thể xử lý chính là nơi mà n à Phương thức ghi đè trong lớp con chỉ
C() được gọi, đó là trong phương thức B().
được phép tung ra các ngoại lệ giống hoặc là
Nếu trong B() cũng không xử lý thì phải xử lý ngoại lệ này trong
lớp con hoặc là tập con của các ngoại lệ đượ
n
A()… Quá trình này gọi là lan truyền ngoại lệ
n Nếu đến main() cũng không xử lý ngoại lệ được tung từ C() thì c tung ra ở lớp cha.
chương trình sẽ phải dừng lại.
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 {
void readFile() throws EOFException {} n Dễ sử dụng
} n Làm chương trình dễ đọc và an toàn hơn
class FloppyDisk extends Disk { n Dễ dàng chuyển điều khiển đến nơi có khả năng xử lý ngoại lệ
void readFile() throws IOException {} // ERROR! n Có thể ném nhiều loại ngoại lệ
}
n Tách xử lý ngoại lệ khỏi đoạn mã thông thường
n Không bỏ sót ngoại lệ (ném tự động)
class Disk {
void readFile() throws IOException {} n Gom nhóm và phân loại các ngoại lệ
}
class FloppyDisk extends Disk {
n KL: Làm chương trình dễ đọc và an toàn
void readFile() throws EOFException {} //OK hơn
}
51
52 52
13
- 9/18/17
Nội dung 4. Tạo ngoại lệ tự định nghĩa
1. Ngoại lệ n 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ó
2. Bắt và xử lý ngoại lệ các lớp ngoại lệ do người dùng định nghĩa.
Kế thừa từ một lớp Exception hoặc lớp con của nó
Ủy nhiệm ngoại lệ
n
3. n Có tất cả các phương thức của lớp Throwable
4. Tạo ngoại lệ tự định nghĩa public class MyException extends Exception {
public MyException(String msg) {
super(msg);
}
public MyException(String msg, Throwable cause){
super(msg, cause);
}
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
Khai báo khả năng tung ngoại lệ
n Bắt và xử lý ngoại lệ
public class FileExample public class Test {
{ public static void main(String[] args) {
public void copyFile(String fName1,String fName2) FileExample obj = new FileExample();
throws MyException try {
{ String a = args[0];
if (fName1.equals(fName2)) String b = args[1];
throw new MyException("File trung ten"); obj.copyFile(a,b);
// Copy file } catch (MyException e1) {
System.out.println("Copy completed"); System.out.println(e1.getMessage());
} }
} catch(Exception e2) {
System.out.println(e2.toString());
}
}
Tung ngoại lệ
}
55 56
14
nguon tai.lieu . vn