Bài giảng Lập trình hướng đối tượng: Xử lý ngoại lệ - Nguyễn Việt Hà

pdf 36 trang phuongnguyen 7070
Bạn đang xem 20 trang mẫu của tài liệu "Bài giảng Lập trình hướng đối tượng: Xử lý ngoại lệ - Nguyễn Việt Hà", để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên

Tài liệu đính kèm:

  • pdfbai_giang_lap_trinh_huong_doi_tuong_xu_ly_ngoai_le_nguyen_vi.pdf

Nội dung text: Bài giảng Lập trình hướng đối tượng: Xử lý ngoại lệ - Nguyễn Việt Hà

  1. Xử lý ngoạilệ
  2. Nội dung „ Khái niệm về xử lý ngoại lệ (exception handling) „ Ném và bắt ngoại lệ „ Khai báo ngoại lệ „ Ném lại ngoại lệ „ Định nghĩa ngoại lệ mới „ Xử lý ngoại lệ trong constructor NguyễnViệtHà Xử lý ngoạilệ 2
  3. Tài liệu tham khảo „ Thinking in Java, chapter 9 „ Java how to program, chapter 15 NguyễnViệtHà Xử lý ngoạilệ 3
  4. Lỗi và ngoạilệ „ Mọi đoạnchương trình đềutiềm ẩnkhả năng sinh lỗi lỗichủ quan: do lập trình sai lỗi khách quan: do dữ liệu, do trạng thái củahệ thống „ Ngoạilệ: các trường hợphoạt động không bình thường „ Xử lý ngoạilệ như thế nào làm thế nào để có thể tiếptục (tái) thựchiện NguyễnViệtHà Xử lý ngoạilệ 4
  5. Cách xử lý lỗi truyềnthống „ Cài đặtmãxử lý tạinơi phát sinh ra lỗi làm cho chương trình trở nên khó hiểu không phải lúc nào cũng đầy đủ thông tin để xử lý không nhất thiết phải xử lý „ Truyềntrạng thái lên mứctrên thông qua tham số, giá trị trả lạihoặc biến tổng thể (flag) dễ nhầm vẫncònkhóhiểu „ Khó kiểmsoátđượchếtcáctrường hợp lỗisố học, lỗi bộ nhớ, „ Lập trình viên thường quên không xử lý lỗi bản chất con người thiếu kinh nghiệm, cố tình bỏ qua NguyễnViệtHà Xử lý ngoạilệ 5
  6. Ví dụ int devide(int num, int denom, int& error) { if (0 != denom) { error = 0; return num/denom; } else { error = 1; return 0; } } NguyễnViệtHà Xử lý ngoạilệ 6
  7. Xử lý ngoạilệ (Exception handling) trong Java „ Xử lý ngoạilệ trong Java đượckế thừatừ C++ „ Dựa trên cơ chế ném và bắtngoạilệ ném ngoạilệ: dừng chương trình và chuyển điều khiểnlên mứctrên (nơi bắt ngoại lệ) bắt ngoạilệ: xử lý vớingoạilệ „ Ngoại lệ: là đối tượng mang thông tin về lỗi đã xảy ra ngoại lệ được ném tự động ngoại lệ được ném tường minh NguyễnViệtHà Xử lý ngoạilệ 7
  8. Phả hệ ngoạilệ trong Java NguyễnViệtHà Xử lý ngoạilệ 8
  9. Ưu điểmcủa ném bắt ngoạilệ „ Dễ sử dụng dàng chuyển điềukhiển đếnnơi có khả năng xử lý ngoạilệ có thể ném nhiều loại ngoại lệ „ Tách xử lý ngoạilệ khỏi thuật toán tách mã xử lý sử dụng cú pháp khác „ Không bỏ sót ngoại lệ (ném tự động) „ Làm chương trình dễđọchơn, an toàn hơn NguyễnViệtHà Xử lý ngoạilệ 9
  10. Ném ngoạilệ (tường minh) „ Ném ngoạilệ bằng câu lệnh throw if (0==denominator) { throw new Exception(); } else res = nominator / denominator; NguyễnViệtHà Xử lý ngoạilệ 10
  11. Cú pháp try - catch „ Việc phân tách đoạn chương trình thông thường và phần xử lý ngoại lệ được thể hiện thông qua cú pháp try – catch Khối lệnh try { }: khối lệnh có khả năng ném ngoại lệ Khối lệnh catch() { }: bắt và xử lý với ngoại lệ try { // throw an exception } catch (TypeOfException e) { exception-handling statements } NguyễnViệtHà Xử lý ngoạilệ 11
  12. Ví dụ try { if (0 == denom) { throw new Exception(”denom = 0”); } else res = num/denom; } catch(Exception e) { System.out.println(e.getMessage()); } NguyễnViệtHà Xử lý ngoạilệ 12
  13. Cú pháp try catch finally „ Có thể bắtnhiềuloại ngoạilệ khác nhau bằng cách sử dụng nhiềukhốilệnh catch đặtkế tiếp khốilệnh catch sau không thể bắt ngoạilệ là lớp dẫnxuấtcủa ngoạilệđượcbắttrong khốilệnh catch trước „ Khốilệnh finally có thểđược đặtcuốicùng để thựchiện các công việc“dọndẹp” cần thiết finally luôn đượcthựchiện dù ngoạilệ có được bắt hay không finally được thực hiện cả khi không có ngoại lệ được ném ra NguyễnViệtHà Xử lý ngoạilệ 13
  14. Cú pháp try catch finally try { } catch(Exception1 e1) { } catch(Exception2 e2) { } finally { } NguyễnViệtHà Xử lý ngoạilệ 14
  15. Ví dụ try { str = buf.readLine(); num = Integer.valueOf(str).intValue(); } catch (IOException e) { System.err.println("IO Exception"); } catch (NumberFormatException e) { System.err.println("NumberFormatException"); } catch(Exception e) { System.err.println(e.getMessage()); } finally { buf.close(); } NguyễnViệtHà Xử lý ngoạilệ 15
  16. Ném ngoạilệ khỏiphương thức „ Không nhất thiết phải xử lý ngoại lệ trong phương thức không đủ thông tin để xử lý không đủ thẩm quyền „ Mộtphương thứcmuốn ném ngoạilệ ra ngoài phải khai báo việc ném ngoạilệ bằng từ khóa throws có thể ném ngoạilệ thuộclớpdẫnxuấtcủa ngoạilệđượckhai báo NguyễnViệtHà Xử lý ngoạilệ 16
  17. Ví dụ int readInt() throws IOException, NumberFormatException { str = buf.readLine(); return Integer.valueOf(str).intValue(); } NguyễnViệtHà Xử lý ngoạilệ 17
  18. Ví dụ try { int n = readInt(); } catch (IOException e) { System.err.println("IO Exception"); } catch (NumberFormatException e) { System.err.println("NumberFormatException"); } NguyễnViệtHà Xử lý ngoạilệ 18
  19. Ngoạilệ và phương thức được định nghĩalại „ Phương thức được định nghĩalạitạilớp dẫnxuấtcóthể không ném ngoại lệ „ Nếu ném ngoại lệ, chỉ có thể ném ngoạilệ giống như tại phương thức của lớp cơ sở hoặc ngoại lệ là lớpdẫnxuấtcủa ngoạilệ đượcnémtạiphương thứccủalớpcơ sở đảmbảobắt đượcngoạilệ khi sử dụng cơ chếđa hình NguyễnViệtHà Xử lý ngoạilệ 19
  20. Ví dụ class A { public void methodA() throws RuntimeException { } } class B extends A { public void methodA() throws ArithmeticException { } } class C extends A { public void methodA() throws Exception { } } class D extends A { public void methodA() { } } NguyễnViệtHà Xử lý ngoạilệ 20
  21. Ví dụ: A a = new B(); try { a.methodA(); } catch (RuntimeException e) { } NguyễnViệtHà Xử lý ngoạilệ 21
  22. Ném lại ngoạilệ „ Sau khi bắt ngoại lệ, nếu thấy cần thiết chúng ta có thể ném lại chính ngoạilệ vừabắt được để cho chương trình mứctrên tiếptụcxử lý try { } catch (Exception e) { System.out.println(e.getMessage()); throw e; } NguyễnViệtHà Xử lý ngoạilệ 22
  23. Lầnvết ngoạilệ StackTrace „ Có thể sử dụng phương thức printStackTrace() để lầnvếtvị trí phát sinh ngoạilệ debug chương trình NguyễnViệtHà Xử lý ngoạilệ 23
  24. public class Test4 { void methodA() throws Exception { methodB(); throw new Exception(); } void methodB() throws Exception { methodC(); throw new Exception(); } void methodC() throws Exception { throw new Exception(); } public static void main(String[] args) { Test4 t = new Test4(); try { t.methodA(); } catch(Exception e) { e.printStackTrace(); } } } NguyễnViệtHà Xử lý ngoạilệ 24
  25. Ném ngoạilệ từ main() „ Nếu không có phương thức nào bắt ngoạilệ, ngoạilệ sẽđượctruyềnlên phương thức main() và đượccần đượcxử lý tại đây. „ Nếuvẫn không muốnxử lý ngoạilệ, chúng ta có thểđểngoạilệ truyền lên mức điềukhiểncủa máy ảobằng cách khai báo main() ném ngoạilệ chương trình sẽ bị dừng và hệ thống sẽ in thông tin về ngoại lệ trên Console (printStackTrace()) NguyễnViệtHà Xử lý ngoạilệ 25
  26. Ví dụ import java.io.*; public class Echo { public static void main(String[] args) throws IOException { InputStreamReader reader; BufferedReader bufReader; reader = new InputStreamReader(System.in); bufReader = new BufferedReader(reader); String s; while( null != (s = bufReader.readLine()) System.out.println(s); } } NguyễnViệtHà Xử lý ngoạilệ 26
  27. Hai loại ngoạilệ „ Java phân biệt hai loại ngoạilệ là ngoạilệ cần kiểmtra vàngoạilệ không cầnkiểmtra „ Ngoạilệ cầnkiểmtra: chương trình dịch luôn kiểm tra xem chúng ta có viết code xử lý vớicác ngoạilệ này không (try catch/ throws) IOException „ Ngoạilệ không cầnkiểmtra: cácngoạilệ có thể loạitrừ nếuviếtchương trình tốthơn RuntimeException NguyễnViệtHà Xử lý ngoạilệ 27
  28. Ví dụ: Checked Exception InputStreamReader reader; BufferedReader bufReader; reader = new InputStreamReader(System.in); bufReader = new BufferedReader(reader); try { String s = bufReader.readLine(); } catch (IOException e) { } NguyễnViệtHà Xử lý ngoạilệ 28
  29. Ví dụ: Unchecked Exception int num1 = Integer.ValueOf(str1).intValue(); int num2 = Integer.ValueOf(str2).intValue(); int num3 = num1 / num2; „ Hầuhết các ngoạilệ thuộclớp RuntimeException đượchệ thống ném tựđộng lỗisố học lỗichỉ số NguyễnViệtHà Xử lý ngoạilệ 29
  30. Hoán đổi ngoạilệ „ Có thểđổi ngoạilệ cầnkiểm tra thành ngoạilệ không cần kiểmtra chưa biết nên làm gì void wrapException() { try { throw new IOException(); } catch (IOException e) { throw new RuntimeException(e); } } NguyễnViệtHà Xử lý ngoạilệ 30
  31. try { wrapException(); } catch (RuntimeException e) { try { throw e.getCause(); } catch (IOException e1) { } } NguyễnViệtHà Xử lý ngoạilệ 31
  32. Tựđịnh nghĩa ngoạilệ „ Chúng ta có thể tạolớp ngoạilệđểphục vụ các mục đích riêng „ Lớp ngoạilệ mới phảikế thừatừ lớp Exception hoặclớpdẫnxuấtcủalớp này „ Có thể cung cấp hai constructor constructor mặc định (không tham số) constructor nhậnmột tham số String và truyền tham số này cho phương thức khởitạo củalớpcơ sở NguyễnViệtHà Xử lý ngoạilệ 32
  33. Ví dụ class SimpleException extends Exception { } class MyException extends Exception { public MyException() {} public MyException(String msg) { super(msg); } } NguyễnViệtHà Xử lý ngoạilệ 33
  34. Khởitạo đốitượng và xử lý ngoạilệ „ Làm thế nào để thông báo khi hàm khởi tạo đốitượng gặplỗi không có giá trị trả lại „ Một cách là khởitạovớimộttrạng thái đặc biệtvàhi vọng sẽ có mã chương trình kiểm tra trạng thái này „ Cách hợplýhơn là ném ngoạilệ NguyễnViệtHà Xử lý ngoạilệ 34
  35. class InputFile { public InputFile(String fname) throws IOException { } } try { InputFile fin = new InputFile(”data.txt”); } catch (IOException e) { System.err.println(e.getMessage); } NguyễnViệtHà Xử lý ngoạilệ 35
  36. Bài tậpvàthực hành „ Tìm hiểuvề phả hệ ngoạilệ củaJava „ Thựchành ném và bắtngoạilệ khai báo phương thức ném ngoạilệ constructor ném ngoạilệ tựđịnh nghĩa ngoạilệ NguyễnViệtHà Xử lý ngoạilệ 36