IS216 - LẬP TRÌNH JAVA Chương 3 NGOẠI LỆ EXCEPTION Nội dung 1. Lambda Expressions và InnerClass 2. Các cách thức xử lý ngoại lệ (Exception Handling) 2 LAMBDA EXPRESSIONS VÀ INNERCLASS Lambda Expressions ● Là biểu thức ẩn danh được sử dụng để biểu diễn một hàm đơn giản. ● Cấu trúc: (parameter1, parameter2, .length() Lambda Expressions ● Ứng dụng: ● Sử dụng với các API Stream: ● filter(), map(), forEach() ● Viết code ngắn gọn hơn: ● Thay thế cho các anonymous inner class ● Tăng khả năng đọc code: ● Code dễ hiểu và dễ bảo trì hơn 5 Lambda Expressions ● Ví dụ: List<String> list = Arrays.println(s)); ● Ví dụ: List<String> languages = Arrays.
● Parameter list: danh sách các tham số. ● Body: biểu thức, câu lệnh xử lý. ● No return type: không có kiểu trả về tường minh, trình biên dịch có thể tự suy luận ra kiểu dữ liệu trả về dựa vào code thực thi. 7 InnerClass ● Là class được định nghĩa bên trong một class khác (hoặc 1 interface khác).
● Có hai loại: ● Static inner class: ○ Được định nghĩa bằng static keyword ○ Có thể truy cập các biến static của outer class ● Non-static inner class: ○ Không được định nghĩa bằng static keyword ○ Có thể truy cập tất cả các biến của outer class 8 InnerClass ● Ứng dụng: ● Tạo các class nhỏ gọn để sử dụng trong một class khác ● Tạo các class ẩn danh để sử dụng với các API như ActionListener ● Cú pháp class Java_Outer_class{ //code class Java_Inner_class{ //code } } 9 InnerClass ● Ví dụ: class OuterClass { private int x = 10; class InnerClass { void print() { System.InnerClass innerClass = outerClass.new InnerClass(); innerClass.print(); } } 10 NGOẠI LỆ Ngoại lệ ● Ngoại lệ (Exception): là một sự kiện xảy ra trong tiến trình thực thi của một chương trình, nó làm ngưng tiến trình bình thường của chương trình. 12 Ngoại lệ ● Khi xảy ngoại lệ, nếu không xử lý chương trình sẽ kết thúc ngay. ● Ví dụ: Lỗi chia cho 0, vượt kích thước của mảng, lỗi mở file, Kết nối mạng bị ngắt trong quá trình thực hiện giao tác, JVM hết bộ nhớ, Truy cập vượt ngoài chỉ số của mảng … 13 Ngoại lệ ● Dựa vào tính chất các vấn đề, người ta chia ngoại lệ thành ba loại: ○ Ngoại lệ được kiểm tra (Checked Exceptions). ○ Ngoại lệ không được kiểm tra (Unchecked Exceptions).
14 Ngoại lệ 15 Ngoại lệ ● Error: là những lỗi nghiêm trọng xảy ra đối khi chương trình hoạt động mà lập trình viên không thể kiểm soát. Ví dụ như lỗi phần cứng, tràn bộ nhớ, hay lỗi của JVM. ● Checked exceptions: là những exception ta phải xử lý ngay khi viết code, vì nó được kiểm tra bởi trình biên dịch Javac. Ví dụ: ClassNotFoundException, NoSuchFieldException.
● Unchecked exceptions: là những excepton chỉ xảy ra khi chương trình chạy, nghĩa là trình biên dịch Javac không "phát hiện" ra khi biên dịch, do vậy programmer không thể xử lý khi viết code. Ví dụ: NullPointerException, ArrayIndexOutOfBoundsException, DivideByZeroException. 16 XỬ LÝ NGOẠI LỆ Xử lý ngoại lệ ● Exception Handling ○ Mục đích: làm cho chương trình không bị ngắt đột ngột. ○ Có 2 cách để xử lý ngoại lệ: ■ Sử dụng các mệnh đề điều kiện kết hợp với các giá trị cờ.
■ Sử dụng cơ chế bắt và xử lý ngoại lệ. 18 Xử lý ngoại lệ ● Sử dụng các mệnh đề điều kiện kết hợp với các giá trị cờ. ○ Mục đích: thông qua tham số, giá trị trả lại hoặc giá trị cờ để viết mã xử lý tại nơi phát sinh lỗi. ○ Hạn chế: ■ Làm chương trình thêm rối, gây khó hiểu.
■ Dễ nhầm lẫn 19 Xử lý ngoại lệ public class Inventory { public final int MIN = 0; public final int MAX = 100; public final int CRITICAL = 10; public boolean addToInventory (int amount) { int temp; temp = stockLevel + amount; if (temp > MAX) { System.println("to become greater than " + MAX + " units (overstock)"); return false; } else { stockLevel = stockLevel + amount; return true; } } // End of method addToInventory 20 Xử lý ngoại lệ ● Các vấn đề đối với cách tiếp cận điều kiện/cờ reference1.method1 (){ if (reference2.method2() == false) return false; } reference2.method2 (){ if (store.addToInventory(amt) == false) return false; } store.addToInventory (int amt){ if (temp > MAX) return false; } 21 Xử lý ngoại lệ reference1.method1 (){ Vấn đề 1: Phương thức if (reference2.method2() == false) chủ có thể quên kiểm tra return false; điều kiện trả về } reference2.method2 (){ if (store.addToInventory(amt) == false) return false; } store.addToInventory (int amt){ if (temp > MAX) return false; } 22 Xử lý ngoại lệ reference1.method1 () if (reference2.method2() == false) return false; reference2.method2 () if (store.addToInventory(amt) == false) return false; store.addToInventory (int amt) Vấn đề 2: Phải sử if (temp > MAX) dụng 1 loạt các phép return false; kiểm tra giá trị cờ trả về 23 Xử lý ngoại lệ reference1.method1 () if (reference2.method2() == false) return false; reference.method2 () if (store.addToInventory(amt) == false) return false; ?? ?? store.addToInventory (int amt) Vấn đề 3: Phương thức if (temp > MAX) chủ có thể không biết return false; 1c1ách xử lý khi lỗi xảy ra 24 Xử lý ngoại lệ ➢ Nhược điểm: o Khó kiểm soát được hết các trường hợp • Lỗi số học, lỗi bộ nhớ,… o Lập trình viên thường quên không xử lý lỗi 25 Xử lý ngoại lệ ● Sử dụng cơ chế bắt và xử lý ngoại lệ. ○ Mục đích: ■ Giúp chương trình đáng tin cậy hơn, tránh kết thúc bất thường ■ 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ệ. ○ Phân loại ngoại lệ: ■ Ngoại lệ không cần kiểm tra (unchecked) ■ Ngoại lệ phải kiểm tra (checked) 26 Xử lý ngoại lệ ● Checked vs Unchecked 27 Xử lý ngoại lệ ● Ngoại lệ unchecked (không cần kiểm tra) ■ Là các ngoại lệ không bắt buộc phải được kiểm tra. ■ Gồm RuntimeException, Error và các lớp con của chúng.
● Ngoại lệ checked (phải kiểm tra) ■ Là các ngoại lệ bắt buộc phải được kiểm tra. ■ Gồm các ngoại lệ còn lại. 28 Xử lý ngoại lệ ● Ngoại lệ không cần kiểm tra ● Trình biên dịch không yêu cầu phải bắt các ngoại lệ khi nó xảy ra. ● Không cần khối try-catch ● Các ngoại lệ này có thể xảy ra bất cứ thời điểm nào khi thi hành chương trình.
● Thông thường là những lỗi nghiêm trọng mà chương trình không thể kiểm soát ● Sử dụng các mệnh đề điều kiện để xử lý sẽ tốt hơn. ● Gồm các lớp RuntimeException, Error và các lớp con của chúng 29 Xử lý ngoại lệ ● Ngoại lệ không cần kiểm tra ● RuntimeException: chỉ các ngoại lệ xảy ra khi JVM thực thi chương trình o NullPointerException: con trỏ null o OutOfMemoryException: hết bộ nhớ o ArrayIndexOutOfBoundsException: vượt quá chỉ số mảng o ArithmeticException: lỗi toán học o ClassCastException: lỗi ép kiểu ➢Lớp Error: o Chỉ những lỗi nghiêm trọng và không dự đoán trước được: ThreadDead, LinkageError, VirtualMachineError… o Các ngoại lệ kiểu Error ít được xử lý. 30 Xử lý ngoại lệ ● Ngoại lệ không cần kiểm tra: NullPointerException int [] arr = null; arr[0] = 1; NullPointerException arr = new int [4]; int i; for (i = 0; i <= 4; i++) arr[i] = i; arr[i-1] = arr[i-1] / 0; 31 Xử lý ngoại lệ ● Ngoại lệ không cần kiểm tra: ArrayIndexOutOfBoundsException int [] arr = null; arr[0] = 1; arr = new int [4]; ArrayIndexOutOfBoundsException int i; (when i = 4) for (i = 0; i <= 4; i++) arr[i] = i; arr[i-1] = arr[i-1] / 0; 32 Xử lý ngoại lệ ● Ngoại lệ không cần kiểm tra: ArithmeticExceptions int [] arr = null; arr[0] = 1; arr = new int [4]; int i; for (i = 0; i <= 4; i++) ArithmeticException arr[i] = i; (Division by zero) arr[i-1] = arr[i-1] / 0; 33 Xử lý ngoại lệ ● Ngoại lệ cần phải kiểm tra ● Là ngoại lệ bắt buộc kiểm tra. ● Phải xử lý khi ngoại lệ có khả năng xảy ra: ● Sử dụng khối try-catch ● Sử dụng throw, throws ● Ví dụ: IOException, NumberFormatException 34 Xử lý ngoại lệ ● Ngoại lệ cần phải kiểm tra: Khối try…catch: ● try{…}: khối lệnh có khả năng gây ra ngoại lệ.
● catch{…}: nơi bắt và xử lý ngoại lệ. ● Cú pháp: try { // Code that may cause an error/exception to occur } catch (ExceptionType identifier) { // Code to handle the exception } ● ExceptionType là một đối tượng của lớp Throwable 35 Xử lý ngoại lệ ● Ngoại lệ cần phải kiểm tra: Đọc dữ liệu từ bàn phím import java.*; class Driver { public static void main (String [] args) { BufferedReader stringInput; String s; int num; stringInput = new BufferedReader(new InputStreamReader(System.in)); 36 Xử lý ngoại lệ ● Ngoại lệ cần phải kiểm tra: Đọc dữ liệu từ bàn phím try{ System.println("You typed in.println("Converted to an integer." + num); } catch (IOException e){ System.println(e); } catch (NumberFormatException e{ : : : } } } 37 Xử lý ngoại lệ ● Ngoại lệ cần phải kiểm tra: Ngoại lệ xảy ra khi nào? try { System.println("You typed in.println("Converted to an integer." + num); } 38 Xử lý ngoại lệ ● Ngoại lệ cần phải kiểm tra ● Kết quả của try phương thức readLine() { System.readLine(); Ngoại lệ có thể xảy ra System.println("You typed in." + s); ở đây num = Integer.println("Converted to an integer." + num); } 39 Xử lý ngoại lệ ● Ngoại lệ cần phải kiểm tra: Lớp BufferedReader ● https://docs.com/javase/7/docs/api/java/io/BufferedReader.html public class BufferedReader { public BufferedReader (Reader in); public BufferedReader (Reader in, int sz); public String readLine () throws IOException; : } 40 Xử lý ngoại lệ ● Ngoại lệ cần phải kiểm tra: Lớp BufferedReader ● Kết quả của phương thức parseInt () try { System.println("You typed in." + s); Ngoại lệ có thể xảy ra num = Integer.parseInt (s); ở đây System.println("Converted to an integer." + num); } 41 Xử lý ngoại lệ ● Ngoại lệ cần phải kiểm tra: Lớp Integer ● http://docs.com/javase/7/docs/api/java/lang/Integer.html public class Integer { public Integer (int value); public Integer (String s) throws NumberFormatException; : : public static int parseInt (String s) throws NumberFormatException; : : } 42 Xử lý ngoại lệ ● Cơ chế xử lý ngoại lệ try { System.println("You typed in.println("Converted to an integer." + num); } catch (IOException e) { System.println(e); } catch (NumberFormatException e) { : : : } } 43 Xử lý ngoại lệ ● Cơ chế xử lý ngoại lệ Integer.main () } try { num = Integer.parseInt (s); } : catch (NumberFormatException e) { : } 44 Xử lý ngoại lệ ● Cơ chế xử lý ngoại lệ Integer.parseInt (String s) { Người sử dụng không Driver.main () nhập chuỗi số try } { num = Integer.parseInt (s); } : catch (NumberFormatException e) { : } 45 Xử lý ngoại lệ ● Cơ chế xử lý ngoại lệ Integer.parseInt (String s) { NumberFormatException e = new Driver.main () NumberFormatException (); try } { num = Integer.parseInt (s); } : catch (NumberFormatException e) { : } 46 Xử lý ngoại lệ ● Cơ chế xử lý ngoại lệ Integer.main () } try { num = Integer.parseInt (s); } : catch (NumberFormatException e) { : } 47 Xử lý ngoại lệ ● Cơ chế xử lý ngoại lệ Integer.