Chương 3 LUỒNG DỮ LIỆU Nội dung • Xử lý biệt lệ • Luồng dữ liệu • Thao tác trên tập tin Exception Handling Xử lý mỗi sử dụng cơ chế biệt lệ trong Java Các cách xử lý lỗi • 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ế xử lý biệt lệ. Ví dụ: Lớp Inventory 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; } Ví dụ: Lớp Inventory (2) else { stockLevel = stockLevel + amount; return true; } } // End of method addToInventory : 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; Các vấn đề đối với cách tiếp cận điều kiện/cờ 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; 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) Vấn đề 2: Phải sử dụng if (temp > MAX) 1 loạt các phép kiểm tra return false; giá trị cờ trả về 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; 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; cách xử lý khi lỗi xảy ra Các cách xử lý lỗi • 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ế xử lý biệt lệ.
Xử lý biệt lệ • Cú pháp: try { // Code that may cause an error/exception to occur } catch (ExceptionType identifier) { // Code to handle the exception } Xử lý biệt lệ: đọc dữ liệu từ bàn phím import java.*; class Driver { public static void main (String [] args) { BufferedReader stringInput; InputStreamReader characterInput; String s; int num; characterInput = new InputStreamReader(System.in); stringInput = new BufferedReader(characterInput); Xử lý biệt lệ: đọ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) { : : : } } } Xử lý biệt lệ: Biệt lệ xảy ra khi nào try { System.println("You typed in.println("Converted to an integer." + num); } Kết quả của phương thức readLine() try { System.readLine(); Biệt lệ có thể xảy ra ở System.println("You typed in." + s); đây num = Integer.println("Converted to an integer." + num); } Lớp BufferedReader http://java.1/docs/api/java/io/BufferedReader.html public class BufferedReader { public BufferedReader (Reader in); public BufferedReader (Reader in, int sz); public String readLine () throws IOException; : } Kết quả của phương thức parseInt () try { System.println("You typed in." + s); Biệt lệ có thể xảy ra ở num = Integer.parseInt (s); đây System.println("Converted to an integer." + num); } Lớp Integer • http://java.1/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; : : } Cơ chế xử lý biệt lệ try { System.println("You typed in.println("Converted to an integer." + num); } catch (IOException e) { System.println(e); } catch (NumberFormatException e) { : : : } } } Cơ chế xử lý biệt lệ Integer.main () } try { num = Integer.parseInt (s); } : catch (NumberFormatException e) { : } Cơ chế xử lý biệt lệ Integer.parseInt (String s) { Người sử dụng không nhập Driver.main () } chuỗi số try { num = Integer.parseInt (s); } : catch (NumberFormatException e) { : } Cơ chế xử lý biệt lệ Integer.parseInt (String s) { NumberFormatException e = } new Driver.main () NumberFormatException (); try { num = Integer.parseInt (s); } : catch (NumberFormatException e) { : } Cơ chế xử lý biệt lệ Integer.parseInt (String s) { NumberFormatException e = } new Driver.main () NumberFormatException (); try { num = Integer.parseInt (s); } : catch (NumberFormatException e) { : } Cơ chế xử lý biệt lệ Integer.main () } try { num = Integer.printStackTrace(); } } } Bắt biệt lệ • catch (NumberFormatException e) Nhập vào: ”exception" • { • System.NumberFormatExcept • } ion: For input string: • } “exception" • } java.NumberFormatException: For input string: “exception" at java.java: 48) at java.java:426) at java.java:476) at Driver.java:39) Các loại biệt lệ • Biệt lệ không cần kiểm tra • Biệt lệ phải kiểm tra Đặc điểm của biệt 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 biệt lệ khi nó xảy ra. – Không cần khối try-catch • Các biệt 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 – Xử dụng các mệnh đề điều kiện để xử lý sẽ tốt hơn. • Ví dụ: – NullPointerException,IndexOutOfBoundsException, ArithmeticException… Biệt 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; Biệt lệ không cần kiểm tra: : ArrayIndexOutOfBoundsException int [] arr = null; arr[0] = 1; arr = new int [4]; int i; for (i = 0; i <= 4; i++) ArrayIndexOutOfBoundsException arr[i] = i; (when i = 4) arr[i-1] = arr[i-1] / 0; Biệt 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++) arr[i] = i; arr[i-1] = arr[i-1] / 0; ArithmeticException (Division by zero) Biệt lệ cần phải kiểm tra • Phải xử lý khi biệt lệ có khả năng xảy ra – Phải sử dụng khối try-catch • Liên quan đến 1 vấn đề cụ thể – Khi một phương thức được gọi thi hành • Ví dụ: – IOException Tránh bỏ qua việc xử lý biệt lệ try { s = stringInput.readLine(); num = Integer.println(e); } Tránh bỏ qua việc xử lý biệt lệ • try • { • • • • } NO! s = stringInput.readLine(); num = Integer.println(e); • } • catch (NumberFormatException e) • { • // Do nothing here but set up the try-catch block to bypass the • // annoying compiler error • } • Mệnh đề finally • Là 1 mệnh đề không bắt buộc trong khối try-catch-finally.
• Dùng để đặt khối lệnh sẽ được thi hành bất kể biệt lệ có xay ra hay không. Mệnh đề finally: có biệt lệ Foo.method(); } catch { } finally { } Mệnh đề finally: có biệt lệ f.method () { try 2) Biệt lệ được tạo ra { } f.method(); } catch { } 4) Thi hành các câu finally lệnh trong khối finally { } Mệnh đề finally: không có biệt lệ f.method () { try 2) Phương thức thi { } hành bình thường f.method(); } } Try-Catch-Finally: Ví dụ public class TCFExample { public void method () { BufferedReader br; String s; int num; try { System.print("Type in an integer: "); br = new BufferedReader(new InputStreamReader(System.readLine(); num = Integer.printStackTrace (); return; } finally { System.println("<<<This code will always execute>>>"); return; } } } Hàm được gọi không thể xử lý biệt lệ method 2 () Exception thrown! method 1 () ??? main () Hàm được gọi không thể xử lý biệt lệ • import java.*; • public class TCExample • { • public void method () throws IOException, NumberFormatException • { • BufferedReader br; • String s; • int num; • System.print("Type in an integer: "); • br = new BufferedReader(new InputStreamReader(System.readLine(); • num = Integer.parseInt(s); • } • } Hàm được gọi không thể xử lý biệt lệ class Driver { public static void main (String [] args) { TCExample eg = new TCExample (); boolean inputOkay = true; Hàm được gọi không thể xử lý biệt lệ • do • { • try • { • eg.printStackTrace(); • } • catch (NumberFormatException e) • { • inputOkay = false; • System.println("Please enter a whole number."); • } • } while (inputOkay == false); • } // End of main • } // End of Driver class Hàm được gọi không thể xử lý biệt lệ class Driver { public static void main (String [] args) { TCExample eg = new TCExample (); boolean inputOkay = true; Hàm được gọi không thể xử lý biệt lệ do { try { eg.printStackTrace(); } catch (NumberFormatException e) { inputOkay = false; System.println("Please enter a whole number."); } } while (inputOkay == false); } // End of main } // End of Driver class Hàm được gọi không thể xử lý biệt lệ class Driver { public static void main (String [] args) { TCExample eg = new TCExample (); boolean inputOkay = true;