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
Trang 1Chương 3
NGOẠI LỆ
EXCEPTION
IS216 - LẬP TRÌNH JAVA
Trang 3LAMBDA EXPRESSIONS
VÀ INNERCLASS
Trang 5Lambda 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
Trang 6List<String> languages = Arrays.asList( "Java" , "C#" , "C++" , "PHP" , "Javascript" );
Collections.sort(languages, (String o1, String o2) -> {
Trang 7Lambda Expressions
● Một biểu thức Lambda (Lambda expression) trong Java gồm các phần chính sau:
● No name: không có tên phương thức, nó là một phương thức
ẩn danh (anonymous method)
● 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
Trang 8● 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
Trang 9● Ứ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ư
}
Trang 10● Ví dụ: class OuterClass {
private int x = 10;
class InnerClass { void print() { System.out.println(x);
} }
public static void main(String[] args) { OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass = outerClass.new InnerClass();
innerClass.print();
} }
Trang 11NGOẠI LỆ
Trang 12Ngoạ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ươngtrình
Trang 13Ngoại lệ
● Khi xảy ngoại lệ, nếu không xử lý chương trình sẽ kết thúc ngay
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 …
Trang 14Ngoạ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)
○ Lỗi (Error)
Trang 15Ngoại lệ
Trang 16Ngoạ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
viết code, vì nó được kiểm tra bởi trình biên dịch Javac Ví dụ:
ClassNotFoundException, NoSuchFieldException
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
Trang 17XỬ LÝ NGOẠI LỆ
Trang 19Xử 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
■ Làm chương trình thêm rối, gây khó hiểu
■ Dễ nhầm lẫn
Trang 20Xử lý ngoại lệ
public class Inventory
{
public final int MIN = 0; public final int MAX = 100;
public final int CRITICAL = 10;
publicboolean addToInventory (int amount)
{
int temp;
temp = stockLevel + amount; if (temp > MAX) {
System.out.print("Adding " + amount + " item will cause stock ");
System.out.println("to become greater than " + MAX + " units (overstock)");
return false;
} else {
stockLevel = stockLevel + amount;
returntrue;
}
Trang 21Xử 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;
Trang 22Xử lý ngoại lệ
reference2.method2 (){
if (store.addToInventory(amt) == false) return false; }
reference1.method1 (){
if (reference2.method2() == false) return false;
}
Vấn đề 1: Phương thức
chủ có thể quên kiểm tra điều kiện trả về
store.addToInventory (int amt){
if (temp > MAX) return false;
}
Trang 23Xử lý ngoại lệ
store.addToInventory (int amt)
if (temp > MAX) return false;
reference2.method2 ()
if (store.addToInventory(amt) == false) return false;
reference1.method1 ()
if (reference2.method2() == false) return false;
Vấn đề 2: Phải sử
dụng 1 loạt các phép kiểm tra giá trị cờ trả về
Trang 24Xử lý ngoại lệ
store.addToInventory (int amt)
if (temp > MAX) return false;
reference.method2 ()
if (store.addToInventory(amt) == false) return false;
reference1.method1 ()
if (reference2.method2() == false) return false;
Vấn đề 3: Phương thức
chủ có thể không biết
c ách xử lý khi lỗi xảy ra
Trang 26■ Ngoại lệ không cần kiểm tra (unchecked)
■ Ngoại lệ phải kiểm tra (checked)
Trang 27Xử lý ngoại lệ
● Checked vs Unchecked
Trang 28Xử 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.
Trang 29Xử lý ngoại lệ
● 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
● 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
Trang 30Xử lý ngoại lệ
● 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
o Chỉ những lỗi nghiêm trọng và không dự đoán trước được: ThreadDead,
LinkageError, VirtualMachineError…
Trang 31Xử lý ngoại lệ
int [] arr = null;
Trang 32Xử lý ngoại lệ
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;
ArrayIndexOutOfBoundsException
(when i = 4)
Trang 33Xử lý ngoại lệ
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)
Trang 34Xử lý ngoại lệ
● 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:
● Ví dụ: IOException, NumberFormatException
Trang 35Xử lý ngoại lệ
● 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ệ
Trang 37System.out.println("Converted to an integer " + num);
}
Trang 38Xử lý ngoại lệ
try
{
System.out.print("Type an integer: "); s = stringInput.readLine();
System.out.println("You typed in " + s); num = Integer.parseInt (s);
System.out.println("Converted to an integer " + num);
}
Trang 39Xử lý ngoại lệ
● Kết quả của phương thức readLine()try
{ System.out.print("Type an integer: ");
Trang 40public BufferedReader (Reader in);
public BufferedReader (Reader in, int sz);
public String readLine () throws IOException;
:
}
Trang 41Xử lý ngoại lệ
● Kết quả của phương thức parseInt ()
try { System.out.print("Type an integer: ");
Trang 42public Integer (int value);
public Integer (String s) throws NumberFormatException;
public static int parseInt (String s) throws NumberFormatException;
}
Trang 43} catch (NumberFormatException e) {
: : :
}
Trang 44Xử lý ngoại lệ
{
: :
}
Driver.main () try
{ num = Integer.parseInt (s);
}
:
catch (NumberFormatException e) {
:
}
Trang 45Xử lý ngoại lệ
Driver.main () try
{ num = Integer.parseInt (s);
}
:
catch (NumberFormatException e) {
:
}
Integer.parseInt (String s) {
Người sử dụng không nhập chuỗi số
}
Trang 46{ num = Integer.parseInt (s);
}
:
catch (NumberFormatException e) {
:
}
Integer.parseInt (String s)
NumberFormatException e = new
NumberFormatException ();
Trang 47Xử lý ngoại lệ
Driver.main () try
{ num = Integer.parseInt (s);
}
:
catch (NumberFormatException e) {
:
}
Integer.parseInt (String s) {
NumberFormatException e = new NumberFormatException ();
}
Trang 48{ num = Integer.parseInt (s);
}
:
catch (NumberFormatException e) {
Ngoại lệ sẽ được xử lý ở đây
}
Trang 49Xử lý ngoại lệ
catch (NumberFormatException e){
}
Trang 50Xử lý ngoại lệ
catch (NumberFormatException e) {
System.out.println(e.getMessage());
System.out.println(e); e.printStackTrace();
}
Trang 51Xử lý ngoại lệ
catch (NumberFormatException e) {
Trang 52Xử lý ngoại lệ
● Bắt ngoại lệ: Tránh bỏ qua việc xử lý ngoại lệ
try {
s = stringInput.readLine();
num = Integer.parseInt (s);
} catch (IOException e) {
//System.out.println(e);
}
Trang 53Xử lý ngoại lệ
try {
s = stringInput.readLine();
num = Integer.parseInt (s);
} catch (IOException e) {
System.out.println(e);
} catch (NumberFormatException e) {
// Do nothing here but set up the try-catch block to bypass the // annoying compiler error
}
NO!
Trang 54Xử lý ngoại lệ
● Khối finally: Là 1 khối không bắt buộc trong khối try-catch-finally.
hay không VD:
oĐóng file, đóng socket, connection
oGiải phóng tài nguyên (nếu cần)
catch block
No exception
exception
Trang 56Xử lý ngoại lệ
● Khối finally: có ngoại lệ
try { f.method();
}
catch { }
finally {
F.method () {
}
Trang 57Xử lý ngoại lệ
try { f.method();
}
catch { }
finally { }
4) Thi hành các câu lệnh trong khối finally
f.method () { 2) Ngoại lệ được tạo} ra
Trang 58Xử lý ngoại lệ
● Khối finally: không có ngoại lệ
try { f.method();
}
catch { }
finally {
}
f.method () {
2) Phương thức thi hành bình thường
Trang 59Xử lý ngoại lệ
● Try-Catch-Finally: Ví dụ
class Driver {
public static void main (String [] args) {
TCFExample eg = new TCFExample ();
eg.method();
} }
Trang 60System.out.print("Type in an integer: ");
br = new BufferedReader(new InputStreamReader(System.in));
s = br.readLine();
num = Integer.parseInt(s);
return;
}
Trang 61Xử lý ngoại lệ
● Từ khóa throws được sử dụng để khai báo một ngoại lệ Nó thể hiện thông tin cho lập trình viên rằng có thể xảy ra một ngoại lệ
● Giả sử có method1 và method2 Method1 gọi method2 và method2 là
phương thức có khả năng xảy ra ngoại lệ:
Trang 62● Cách 2: Khai báo throws
public static void main( String [ ] args) throws IOException
{
String s = buff.readLine();
62
Trang 63Xử lý ngoại lệ
main ()
method 2 ()
Xảy ra ngoại lệ
method 1 () throws IOException
Method2()
Hoặc
method 1 (){
try { method2() }
catch(){….}
}
Trang 65Xử lý ngoại lệ
65
class Driver {
public static void main (String [] args) { TCExample eg = new TCExample ();
boolean inputOkay = true;
} // End of main 50
Phải xử lý cả IOException và NumberFormatException
Hàm main xử lý ngoại lệ
Trang 66Xử lý ngoại lệ
● Hàm main không xử lý ngoại lệ
class Driver {
public static void main (String [] args) throws IOException, NumberFormatException {
TCExample eg = new TCExample ();
eg.method();
} }
Trang 67Xử lý ngoại lệ
● Từ khoá throw được sử dụng để ném ra một ngoại lệ cụ thể, chủ yếu được sử dụng để ném ngoại lệ tùy chỉnh (ngoại lệ do người
dùng tự định nghĩa)
Trang 68Xử lý ngoại lệ
➢Sử dụng throw anExceptionObject trong thân
phương thức để tung ra ngoại lệ khi cần
➢Nếu phương thức có chứa câu lệnh throw ngoại lệ thì phần khai báo phương thức phải khai báo throws
ngoại lệ đó hoặc lớp cha của ngoại lệ đó.
Trang 69Xử lý ngoại lệ
➢Đối với RuntimeException phương thức không cần
phải khai báo throws RuntimeException vì ngoại lệ này mặc định được ủy nhiệm cho JVM
Trang 70return num;
} public static void main(String[] args) { int num = cal(6,0);
} Lỗi ngoại lệ:
Exception in thread "main" java.lang.ArithmeticException: Khong the chia cho 0
Trang 71return num;
} public static void main(String[] args) { int num = cal(6,0);
}
Lỗi biên dịch:
Exception in thread "main" java.lang.RuntimeException:
Uncompilable source code - unreported exception java.lang.Exception;
must be caught or declared to be thrown
at exceptionex.ExceptionEx.main(ExceptionEx.java:58)
Trang 72return num;
} public static void main(String[] args) throws Exception{
int num = cal(6,0);
}
Thêm: throws Exception
Trang 73Sau throw là một instance Sau throws là một hoặc nhiều class.
Throw được sử dụng trong phương thức có thể
quăng ra Exception ở bất kỳ dòng nào trong
phương thức (sau đó dùng try-catch để bắt hoặc
throws cho phương thức khác xử lý)
Throws được khai báo ngay sau dấu đóng ngoặc đơn của phương thức Khi một phương thức có throw bên trong mà không bắt lại (try – catch) thì phải ném đi (throws) cho phương thức khác xử lý.
Không thể throw nhiều exceptions.
Có thể khai báo nhiều exceptions, Ví dụ:
public void method() throws IOException, SQLException { }
Trang 74Xử lý ngoại lệ
➢ Một phương thức có thể throw nhiều hơn 1 ngoại lệ:
public void method(int tuoi, String ten) throws ArithmeticException,
➢ Lan truyền ngoại lệ:
Trang 75Xử lý ngoại lệ
oNếu C() gặp lỗi và throw ra ngoại lệ nhưng trong C() lại không xử lý ngoại
lệ này, thì nơi gọi C() là phương thức B() là nơi có thể xử lý ngoại lệ.
oNếu trong B() cũng không xử lý thì phải xử lý ngoại lệ này trong A()… Quá trình này gọi là lan truyền ngoại lệ.
oNếu đến main() cũng không xử lý ngoại lệ được throw từ C() thì chương
trình sẽ phải dừng lại.
C() B() A()
B() A() main()
C() tung ngoại lệ
Trang 76Xử lý ngoại lệ
● Trong khối catch, ta có thể không xử lý trực tiếp ngoại lệ mà lại ném lại
ngoại lệ đó cho nơi khác xử lý.
● Chú ý: Trong trường hợp trên, phương thức chứa catch phải bắt ngoại lệ hoặc khai báo throws cho ngoại lệ
catch ( IOException e) {
throw e;
}
Trang 78Xử lý ngoại lệ
class Disk {
public void readFile() throws EOFException {}
} class FloppyDisk extends Disk {
public void readFile() throws IOException {} // ERROR!
class FloppyDisk extends Disk {
public void readFile() throws EOFException {}
}
Trang 79Xử lý ngoại lệ
➢ Ưu điểm của throws/throw
➢ Dễ sử dụng
oDễ dàng chuyển điều khiển đến nơi có khả năng xử lý ngoại lệ
oCó thể throw nhiều loại ngoại lệ
➢ Tách xử lý ngoại lệ khỏi đoạn mã thông thường
➢ Không bỏ sót ngoại lệ (throws)
➢ Gom nhóm và phân loại các ngoại lệ
Trang 80Tạo ra kiểu ngoại lệ mới
Trang 81Lớp Exception
Exception
IOException
ClassNotFound Exception
CloneNotFound Exception
EOFException FileNotFound
Exception
MalformedURL Exception
UnknownHost Exception
Trang 82Tạo ngoại lệ mới
➢Mục đích: tạo ra ngoại lệ do người dùng định nghĩa để kiểm soát các lỗi
oKế thừa lớp Exception hoặc lớp con của nó
oCó tất cả phương thức của lớp Throwable
Trang 83Tạo ngoại lệ tự định nghĩa
Trang 84Sử dụng ngoại lệ tự định nghĩa
● Sử dụng ngoại lệ
public class Example {
public void kiemTra(String fName1,String fName2) throws
Khai báo khả năng tung ngoại lệ
Tung ngoại lệ
Trang 85Sử dụng ngoại lệ tự định nghĩa
public class Test { public static void main( String [] args) { Example ex= new Example();
try { String a = “Test”;
String b = “Test”;
ex.kiemTra(a,b);
} catch (MyException e) { System.out.println(e.getMessage());
} } }
Trang 86Cây thừa kế của lớp IOExceptions
Trang 88Vấn đề bắt ngoại lệ
} catch (IOException e) {
} catch (EOFException e) {
}
try {
} catch (EOFException e) {
} catch (IOException e) {
}
try {
Trang 89Q & A
Giảng viên: Tạ Việt Phương
E-mail: phuongtv@uit.edu.vn