1. Trang chủ
  2. » Công Nghệ Thông Tin

giáo trình java tóm tắt - exceptions

10 419 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 132,5 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Trong quá trình thi hành, chương trình có thể phát sinh những lỗi khác, gọi là lỗi thực thi run-time errors ví dụ như truy cập vượt quá độ dài mảng, gọi tới một đối tượng chưa được khởi

Trang 1

1 Giới thiệu 1

2 Khối exception cơ bản 1

3 Tổ chức exception trong Java 3

4 Phát sinh exception 4

4.1 Từ khóa throw 4

4.2 Từ khóa throws 5

5 Exception handling với multi-catch 5

6 Sự lan truyền exception 7

7 Các phương thức chính của Exception 8

8 Exception tự định nghĩa 9

9 Overriding với exception 10

1 Giới thiệu

Thông thường, khi lập trình, ta sẽ bất lỗi trong lúc biên dịch Tuy nhiên đó chỉ là lỗi cú pháp Trong quá trình thi hành, chương trình có thể phát sinh những lỗi khác, gọi là lỗi thực thi (run-time errors) ví dụ như truy cập vượt quá độ dài mảng, gọi tới một đối tượng chưa được khởi tạo, …

Với những ngôn ngữ "cổ điển" như C, Pascal,… thì việc kiểm tra và xử lý hết các lỗi run-time là vấn đề không dễ dàng Nếu xử lý không hết, những lỗi run-run-time sẽ ảnh hưởng trực tiếp đến người dùng và dễ gây cảm giác không tin tưởng vào chương trình Để xử lý lỗi trong các ngôn ngữ này, ta có thể dùng các giá trị quy ước trong kiểu trả về (ví dụ như trả

về null nếu lấy dữ liệu từ một stack rỗng) hoặc cập nhật giá trị cho các biến trạng thái (flag) Tuy nhiên, nếu kiểm tra và xử lý hết tất cả các lỗi run-time, chương trình sẽ trở nên rất cồng kềnh và khó đọc do có quá nhiều câu lệnh kiểm tra điều kiện

Các ngôn ngữ sau này như C++, Visual Basic, … có một phương pháp mới để chặn các lỗi run-time, gọi là exception handling Với phương pháp này, ta chỉ cần chỉ ra nơi có thể gây lỗi (exception) và nơi xử lý lỗi (exception handler) Tuy nhiên, trong C++, exception handlingcòn rất "sơ khai", chưa đầy đủ và khó dùng

Trong Java, có một nguyên tắc là "những đoạn code lỗi sẽ không bao giờ được thực thi" Theo nguyên tắc này, Java cung cấp các lớp chuyên cho xử lý lỗi (đại diện là Throwable,

Error, Exception,…) và việc kiểm tra exception được cài đặt sẵn trong tất cả các lớp thư viên của Java Ngoài ra, Java còn cho phép lập trình viên tự kiểm tra exception, tự phát sinh exception và tự định nghĩa các exception mới

2 Khối exception cơ bản

Một khối exception cơ bản gồm 2 khối lệnh chính: khối try và khối catch

Khối try: là nơi chứa đoạn lệnh có khả năng gây ra lỗi run-time Mỗi khối exception có đúng một khối try

Trang 2

Khối catch: là nơi chứa đoạn lệnh xử lý lỗi do khối try phát hiện Một khối exception

có thể có một hay nhiều khối catch, mỗi khối catch ứng với một hay vài loại lỗi nhất định Cách dùng khối exception với nhiều khối catch sẽ được trình bày sau

Ngoài ra còn khối tùy chọn là finally, là nơi chứa các lệnh luôn được thực thi dù có phát sinh exception hay không Nếu trong khối catch có lệnh thoát khỏi phương thức, như return, thì lệnh trong khối finally vẫn được thực thi bình thường Các lệnh này thường là những lệnh "dọn dẹp" bộ nhớ, đóng các stream,…

Cú pháp tổng quát:

try

{

// Các câu lệnh có khả năng gây ra exception

}

catch (Exception1 E1)

{

// Các câu lệnh xử lý cho exception thuộc loại Exception1

}

catch (Exception2 E2)

{

// Các câu lệnh xử lý cho exception thuộc loại Exception2

}

finally

{

// Các câu lệnh luôn được thực thi

}

Ví dụ cụ thể: Trong ví dụ này, ta sẽ cố tình phát sinh ra một exception, đó là lỗi chia cho

0 Lỗi này chỉ được phát hiện lúc run-time

public class Main01

{

public static void main(String[] args)

{

int x=4,y=0;

try

{

int z=x/y;

// Câu lệnh này sẽ không được thực thi

System.out.println( "Hello!" );

}

catch(Exception E)

{

System.out.println( "Co loi run-time!" );

} }

}

Và kết quả khi chạy chương trình:

Co loi run-time!

Press any key to continue

Nếu không xử lý exception, ta sẽ được kết quả như sau:

Trang 3

Exception in thread "main" java.lang.ArithmeticException: / by zero

at Main01.main(Main01.java:8)

Press any key to continue

Đó là exception do Java tự phát hiện và xử lý

Qua ví dụ trên ta, thấy rằng khi một câu lệnh phát sinh exception, các câu lệnh sau nó trong khối try sẽ không được thực thi Khi đó, con trỏ lệnh sẽ nhảy ngay đến khối catch

phù hợp (nếu có) để thực thi các lệnh trong đó

3 Tổ chức exception trong Java

Trong Java, các exception được hiện thực qua class cao nhất là Throwable, dưới nó là hai lớp con Exception và Error Tất cả các exception trong Java đều kế thừa từ hai lớp này Một đối tượng phải được dẫn xuất từ Throwable mới dùng được trong câu lệnh throw để phát sinh exception (sẽ trình bày sau)

Class Exception dùng để mô tả chung cho tất cả exception trong Java, … Trong đó,

RuntimeException là một dẫn xuất quan trọng Từ nó, các exception như lỗi vượt phạm

vi mảng, lỗi tính toán số học, lỗi ép kiểu, lỗi sử dụng đối tượng chưa khởi tạo,… được cài đặt

Class Error dùng để mô tả các chung cho các loại exception đặc biệt, không cần xử lý, ví

dụ như lỗi của máy ảo, lỗi liên kết class,…

Hình 1 Sơ đồ tổ chức exception của Java

Throwable

RuntimeException

ClassCastException NullPointerException ArithmeticException

VirtualMachineError

Trang 4

4 Phát sinh exception

4.1 Từ khóa throw

Trong ví dụ trên, ta thấy exception được phát sinh khi tiến hành chia một số cho 0 Đó là exception do Java phát sinh

Ngoài ra, ta cũng có thể tự phát sinh các exception khi cần bằng câu lệnh throw Khi

"throw" một exception, ta cần phải biết loại của nó để phát sinh cho phù hợp

public class Main02

{

public static void main(String[] args)

{

Object o=null;

if (o==null)

// Phát sinh exception loại NullPointerException

throw new NullPointerException();

}

}

Trong đó, NullPointerException là một exception có sẵn của Java Khi chạy chương trình, ta sẽ nhận được thông báo sau:

Exception in thread "main" java.lang.NullPointerException

at Main02.main(Main02.java:8)

Để exception được rõ nghĩa, ta có thể throw một exception với constructor có tham số là chuỗi mô tả loại lỗi, sau đó dùng phương thức getMessage() để xuất câu thông báo ra màn hình

public class Main02

{

public static void main(String[] args)

{

try

{

String S= "Loi: object co gia tri null" ;

// Tạo ra exception bằng constructor có tham số

throw new NullPointerException(S);

}

catch (NullPointerException E)

{

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

} }

}

Khi đó, câu thông báo lỗi sẽ trở nên thân thiện hơn:

Loi: object co gia tri null

Press any key to continue

Trang 5

4.2 Từ khóa throws

Ngoài cách throw exception thông thường, ta cũng có thể throw một exception ngay trong một khối catch Khi đó, exception này sẽ được phần exception handling ở cấp cao hơn xử lý, các khối catch phù hợp ở cùng mức sẽ bị bỏ qua

Nếu một phương thức có phát sinh ra exception cho khối cao hơn xử lý, nó phải được khai báo với từ khóa throws

// Từ khóa throws cho biết phương thức này có phát sinh exception

// cho khối cao hơn xử lý

void methodD(int[]a)throws NullPointerException

{

if (a == null)

// Phát sinh exception

throw new NullPointerException("Loi: Mang null" );

//

}

Khi đó, nếu phương thức methodC() gọi methodD() mà không đặt nó trong khối exception thì cũng phải có từ khóa throws trong phần khai báo Khi đó exception của phương thức methodC() phải cùng loại hoặc là lớp cha của exception do methodD()

phát sinh

void methodC()throws NullPointerException // Hoặc throws Exception,

{

int[]a=null;

//

methodD(a);

//

}

5 Exception handling với multi-catch

Như đã nói ở trên, ta có thể dùng nhiều khối catch trong một khối exception handling, mỗi khối catch ứng với một hoặc nhiều exception Xem ví dụ sau:

Scanner sn=new Scanner(System.in);

System.out.print ("Nhap gia tri n (0, 1, 2, ): " );

int n=sn.nextInt();

try

{

switch (n)

{

case 0 : break; // Không phát sinh exception

case 1 : throw new NullPointerException();

case 2 : throw new ClassCastException();

case 3 : throw new ArrayIndexOutOfBoundsException();

default:

// Phát sinh exception IllegalArgumentException // Lưu ý: không có khối catch riêng cho exception này, // việc catch nó sẽ do khối cach Exception thực hiện

Trang 6

throw new IllegalArgumentException();

}

}

catch (NullPointerException E)

{

System.out.println( "Loi doi tuong null!" );

// return sẽ ngăn cản việc thực thi khối lệnh ngoài finally,

// nhưng không ngăn cản việc thực thi khối lệnh finally

return;

}

catch (ClassCastException E)

{

System.out.println ("Loi ep kieu!" );

}

catch (ArrayIndexOutOfBoundsException E)

{

System.out.println ("Loi chi so mang vuot pham vi!" );

}

catch (Exception E)

{

System.out.println ("Co loi!" );

}

finally

{

// Khối lệnh này luôn được thực thi

System.out.println( "Khoi lenh finally." );

}

// Lệnh này có khi được thực thi, có khi không, tùy vào cách xử lý của // các khối catch ở trên

System.out.println ("Lenh ngoai khoi finally." );

Khi được thực thi, tùy vào giá trị của n mà đoạn code trên sẽ phát sinh exception tương ứng Khi đó chỉ đó chỉ có khối catch phù hợp nhất được thực thi

Nhập n = 0: không phát sinh exception nên không thực thi khối catch nào, vẫn thực thi khối finally và lệnh ngoài khối finally

Nhap gia tri n (0, 1, 2, ): 0

Khoi lenh finally.

Lenh ngoai khoi finally.

Press any key to continue

Nhập n = 1: phát sinh NullPointerException, khối catch tương ứng với exception này chứa lệnh return thoát ngay khỏi phương thức nên lệnh ngoài khối finally không được thực thi, tuy nhiên lệnh trong khối finally vẫn được thực thi bình thường

Nhap gia tri n (0, 1, 2, ): 1

Loi doi tuong null!

Khoi lenh finally.

Press any key to continue

Nhập n = 2: phát sinh ClassCastException, khối catch tương ứng với exception này không thoát khỏi phương thức nên lệnh ngoài khối finally vẫn được thực thi, và dĩ nhiên lệnh trong khối finally vẫn được thực thi bình thường

Nhap gia tri n (0, 1, 2, ): 2

Trang 7

Loi ep kieu!

Khoi lenh finally.

Lenh ngoai khoi finally.

Press any key to continue

Mỗi loại exception sẽ ứng với một đối tượng exception trong Java Nếu ta "catch" một exception thì ta đã "catch" luôn các exception kế thừa từ nó Nên cần lưu ý rằng Java không cho phép ta "catch" exception "cha" trước khi "catch" exception "con", vì như vậy thì khối lệnh catch của exception "con" sẽ không bao giờ được thực thi

Trong khối catch cuối cùng, ta bắt lỗi với loại lỗi là Exception Do mọi exception thông thường trong Java đều kế thừa từ class Exception nên khối catch này có khả năng bắt gần như mọi loại exception của Java Do đó, như đã nói ở trên, khối catch của nó phải được đặt sau cùng (nếu có)

Dĩ nhiên là nếu muốn catch mọi loại exception trong Java, ta có thể catch với loại lỗi là

Throwable:

catch (Throwable T)

{

System.out.println ("Co loi trong Java!" );

}

6 Sự lan truyền exception

Khi một exception được phát sinh, nó sẽ lan truyền dần từ nơi phát sinh ra các cấp cao hơn cho tới khi được catch hoặc tới phương thức main() Khi exception truyền tới

main() mà vẫn không được catch, nó sẽ được thông báo cho người dùng

Xem ví dụ sau:

public class Main04

{

public static void main(String[] args)

{

methodA(null);

}

static void methodA(int[] a)

{

methodB(a);

}

static void methodB(int[] b)

{

System.out.println(b[0]);

}

}

Và kết quả khi chạy ví dụ trên:

Exception in thread "main" java.lang.NullPointerException

at Main04.methodB(Main04.java:13)

at Main04.methodA(Main04.java:9)

at Main04.main(Main04.java:5)

Press any key to continue

Dựa vào thông báo, ta có thể thấy exception NullPointerException được phát sinh từ

methodB(), sau đó được lan truyền về methodA() và sau cùng là main()

Trang 8

7 Các phương thức chính của Exception

Các phương thức dưới đây đều kế thừa từ Throwable

Exception() Khởi tạo một Exception mặc định, câu thông báo sẽ

null

Exception(String msg) Khởi tạo một Exception với câu thông báo msg String getMessage() Lấy câu thông báo của Exception

void printStackTrace() In ra stack lan truyền của Exception

Throwable fillInStackTrace() Ghi thông tin của Exception vào stack lan truyền,

sau đó trả về chính Exception this

StackTraceElement[]

getStackTrace()

Lấy ra mảng chứa các StackTraceElement, mỗi

StackTraceElement là một đối tượng chứa thông tin về Exception được lan truyền (gồm dòng, file, lớp, phương thức gây lỗi)

Ví dụ:

public static void main(String[] args)

{

StackTraceElement[]ste=null;

try

{

methodA();

}

catch (Exception E)

{

// In ra câu thong bao loi

System.out.println( "Co loi: " +E.getMessage());

// Lấy ra stack lưu thông tin về sự lan truyền exception

ste=E.getStackTrace();

}

for(int i=0; ste!=null && i<ste.length; i++)

System.out.println (

" Noi gay loi: Tap tin " + ste[i].getFileName() + " Dong " + ste[i].getLineNumber() +

" Class " + ste[i].getClassName() +

" Phuong thuc: " + ste[i].getMethodName()

);

}

static void methodA()throws Exception

{

methodB();

}

static void methodB()throws Exception

{

throw new ArrayIndexOutOfBoundsException("Loi chi so mang." ); }

Kết quả chạy đoạn ví dụ trên:

Co loi: Loi chi so mang.

Noi gay loi: Tap tin Main05.java Dong 34 Class Main05 Phuong thuc: methodB

Noi gay loi: Tap tin Main05.java Dong 30 Class Main05 Phuong thuc: methodA

Trang 9

Noi gay loi: Tap tin Main05.java Dong 11 Class Main05 Phuong thuc: main Press any key to continue

8 Exception tự định nghĩa

Ngoài việc dùng các exception có sẵn của Java, ta có thể tự tạo các exception cho phù hợp với chương trình của mình

Để tạo một exception, ta chỉ cần tạo một class kế thừa từ Throwable (hoặc kế thừa từ các lớp con của Throwable), sau đó cài đặt các phương thức phù hợp

Ví dụ: cài đặt exception LoiDiemSo cho điểm trung bình của học sinh: nếu nhập điểm nhỏ hơn 0 hoặc lớn hơn 10 thì chương trình sẽ phát sinh exception này

// Khai báo exception LoiDiemSo

// Exception này sẽ được phát sinh khi nhập điểm không hợp lệ

public class LoiDiemSo extends Exception

{

public LoiDiemSo()

{

super("Diem phai tu 0 toi 10" );

}

public LoiDiemSo(String s)

{

super(s);

}

}

Sau khi đã có exception LoiDiemSo, ta có thể dùng như sau:

//

public void Nhap()throws LoiDiemSo

{

Scanner sn=new Scanner(System.in);

System.out.print( " + Nhap ten hoc sinh: " );

HoTen=sn.nextLine();

System.out.print( " + Nhap dien trung binh : " );

DiemTrungBinh=sn.nextFloat();

// Neu diem khong hop le thi phat sinh exception LoiDiemSo

if (DiemTrungBinh<0 || DiemTrungBinh>10)

throw new LoiDiemSo();

}

Trong phương thức main, khi nhậo học sing, ta sẽ bắt lỗi và xuất ra câu thông báo:

public static void main(String[] args)

{

HocSinh hs=new HocSinh();

try

{

hs.Nhap();

}

catch (LoiDiemSo L)

{

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

Trang 10

}

System.out.println(hs);

}

9 Overriding với exception

Khi một lớp con override phương thức của lớp cha, nếu lớp cha có ném ra lỗi E (qua từ khóa throws) thì lớp con cũng phải ném ra lỗi E hoặc lỗi con của E

class LopCha

{

public void Method1()throws Exception

{

}

public void Method2()throws RuntimeException

{

}

public void Method3()throws ClassCastException

{

}

}

class LopCon extends LopCha

{

// OK, vì NullPointerException là con của Exception

public void Method1()throws NullPointerException

{

}

// OK, vì cha và con ném ra cùng loại lỗi là RuntimeException

public void Method2()throws RuntimeException

{

}

// Phương thức này không hợp lệ

// vì Exception là cha của ClassCastException

/*

public void Method3()throws Exception

{

}

*/

}

Ngày đăng: 24/10/2014, 00:34

HÌNH ẢNH LIÊN QUAN

Hình 1 Sơ đồ tổ chức exception của Java - giáo trình java tóm tắt - exceptions
Hình 1 Sơ đồ tổ chức exception của Java (Trang 3)

TỪ KHÓA LIÊN QUAN

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

w