Các loại lỗi của chương trình
Cấu trúc các lớp quản lý lỗi của Java.
Bẫy lỗi bằng try.catch.finally
Lan truyền lỗi
Xuất Exception
Tựđịnh nghĩa Exception
15 trang |
Chia sẻ: haohao89 | Lượt xem: 2136 | Lượt tải: 1
Bạn đang xem nội dung tài liệu Bài giảng Xử lý biệt lệ, để tải tài liệu về máy bạn click vào nút DOWNLOAD ở trên
1XỬ LÝ BIỆT LỆ
(Handling Exception)
2
Mục tiêu
Giải thích được lỗi cú pháp và lỗi thực thi chương trình.
Giải thích được mô hình đối tượng Exception của Java.
Giải thích được cú pháp bẫy lỗi bằng try...catch... finally.
Sử dụng được throw và throws trong code,
Tự định nghĩa được Exception.
3
Nội dung
Các loại lỗi của chương trình
Cấu trúc các lớp quản lý lỗi của Java.
Bẫy lỗi bằng try...catch...finally
Lan truyền lỗi
Xuất Exception
Tự định nghĩa Exception
4
Các loại lỗi của chương trình
Bài toán Code
Chương trình
Hiện
thực Compile
Run
Syntax error
No
Syntax error
Correct resultEND
BEGIN
Run-time error
( Exception )
Wrong result
?
5
Các loại lỗi của chương trình
Compile-time error = Syntax error
Run-time error = Exception, tình huống bất bình thường đã xẩy ra
trong khi chương trình thực thi.
Khi có Exception:
Có thể là máy bị treo (halt).
Chương trình ngắt đột ngột, điều khiển trả về cho OS, OS thu hồi
bộ nhớ của chương trình ( đuổi ra ngoài ).
Cần có cơ chế điều khiển tình huống này.
6
Giới thiệu về biệt lệ
Là một kiểu lỗi đặc biệt, nó xảy ra trong thời gian thực thi đoạn
lệnh
Thông thường các điều kiện thực thi chương trình gây ra biệt lệ
Khi một biệt lệ xuất hiện, thì việc thực thi chương trình có thể kết
thúc đột ngột và trả quyền điều khiển chương trình cho hệ thống.
Vài biệt lệ: người sử dụng nhập vào dữ liệu không hợp lệ, không
tìm thấy file cần mở, kết nối mạng bị đứt khi giao tiếp, hoặc JVM
vượt quá bộ nhớ…
ERROR !!
Ví dụ :
7Zero.java
public class Zero
{
public static void main (String[] args)
{
int tu = 10;
int mau = 0;
System.out.println (tu / mau);
System.out.println ("This text will not be printed.");
}
}
ERROR
8
ArrayDemo.java
public class ArrayDemo
{
public static void main (String[] args)
{
int[] codes = new int[10];
for (int i=0; i <= 10; i++)
codes[i] = codes[i] * 2;
System.out.println ("This text will not be printed.");
}
}
9
Xử lý biệt lệ
Mục đích của việc xử lý biệt lệ là làm giảm thiểu việc kết thúc bất
thường của hệ thống và của chương trình.
Ví dụ, thao tác xuất/nhập trong một tập tin, nếu việc chuyển đổi kiểu dữ
liệu không thực hiện đúng, một biệt lệ sẽ xảy ra và chương trình bị hủy
mà không đóng tập tin. Lúc đó tập tin sẽ bị hư hại và các nguồn tài
nguyên được cập phát cho tập tin không được thu hồi lại cho hệ thống.
Một chương trình có thể xử lý một biệt lệ trong 3 cách:
Bỏ qua
Xử lý biệt lệ tại nơi biệt lệ xuất hiện
Xử lý biệt lệ tại một phần khác trong chương trình
Trong một chương trình, nếu một biệt lệ được bỏ qua, chương trình sẽ
kết thúc bất thượng và đưa ra thông báo lỗi tương ứng
10
Xử lý biệt lệ
Khi một biệt lệ xảy ra, đối tượng tương ứng với biệt lệ đó sẽ
được tạo ra.
Đối tượng này sau đó được truyền tới phương thức nơi mà biệt lệ
xảy ra.
Đối tượng này chứa các thông tin chi tiết về biệt lệ. Thông tin
này có thể nhận được và xử lý.
Lớp ’throwable’ mà Java cung cấp là lớp trên nhất của lớp biệt
lệ.
11
Cấu trúc các lớp quản lý lỗi của Java
Java là ngôn ngữ mạnh (robust) nên có các hỗ trợ giúp tối thiểu
hóa các exception.
Khi có run-time error, thông tin về lỗi này được máy ảo tự động
phát ra thông qua một đối tượng Exception. Đây là đối tượng được
phát sinh động (dynamic thrown object) từ máy ảo, Đối tượng này
có thể bẫy từ chương trình nhờ cơ chế giao tiếp giữa máy ảo và
chương trình.
Java cung cấp một tập rất nhiều các lớp mô tả các lỗi cùng với cơ
chế bẫy lỗi giúp developer có thể quản lý các exception trong code
của chương trình.
Gói java.lang định nghĩa rất nhiều lớp lỗi run-time.
Tham khảo Java Documentation.
12
Cấu trúc các class quản lý lỗi của Java
Object
Throwable
ExceptionError
AWTError
ThreadDead
…
SQLException
ClassNotFoundException
…
RuntimeException
ArithmeticException
NullPointerException
NumberFormatExceptionKhi 1 error/exception xảy ra, ta
nói rằng nó bị “thrown” (throw) …
13
Lớp Throwable
Các lớp Exception đều được dẫn ra từ lớp này.
Chứa các hành vi giúp truy xuất thông tin về lỗi như:
nội dung mô tả lỗi : getMesage(), toString()
nội dung stack lúc gây lỗi: getStackTrace(), printStackTrace(),
....
14
Một số lớp quản lý lỗi của Java
class Giải thích
Exception Lớp nền của các run-time error
RuntimeException Lớp nền của nhiều lớp run-time error
ArithmeticException Lỗi do thực thi một phép toán
IllegalArgumentException Lỗi sai đối số của hàm
ArrayIndexOutOfBoundsException Lỗi do chỉ số ngoài tầm của mảng
NullPointerException Lỗi do truy xuất một đối tượng mà chưa khởi
tạo
SecurityException Lỗi do truy xuất bị cấm
ClassNotFoundException Lỗi do không tìm thấy file.class
15
Một số lớp quản lý lỗi của Java
class Giải thích
NumberFormatException Lỗi do không đúng dạng số
IOException Lỗi xuất nhập
FileNotFoundException Lỗi do không tìm thấy file
EOFException Lỗi do cố truy xuất nội dung 1 file khi đã ở cuối
file
IllegalAccessException Lỗi do truy xuất 1 class bị cấm
NoSuchMethodException Lỗi do viết sai tên hành vi
InterruptedException Lỗi do ngắt ngang 1 luồng lệnh đang được thực
thi
16
Mô hình xử lý biệt lệ
Mô hình được biết đến là mô hình ‘catch and throw’
Khi một lỗi xảy ra, biệt lệ sẽ đuợc chặn và được đưa vào một
khối.
Từ khóa để xử lý biệt lệ:
try
catch
throw
throws
finally
17
Bẫy lỗi bằng try...catch...finally
Để chương trình vẫn có thể tiếp tục hoạt động, người lập trình cần
phải dự đoán lỗi có thể xẩy ra để bẫy lỗi.
Bẫy lỗi bằng cú pháp: try...catch ...finally ...
try
{
}
catch ( Exception1 e1)
{
}
catch ( Exception2 e2)
{
}
finally
{
}
// Buộc phải có {...} dù chỉ có 1 phát biểu
18
Bẫy lỗi bằng try...catch...finally
Dự đoán lỗi:
Tại một thời điểm, developer có thể dự đoán chính xác các lỗi có
thể xảy ra. Ví dụ: Nhập dữ liệu từ bàn phím vào 1 số thông qua
hộp thoại, có 2 tình huống: người dùng không nhập (user cancel),
người dùng nhập chữ.
Có thể tổng quát hoá các lỗi nhờ lớp cha (Exception) để quản lý
chung.
19
Khối lệnh ‘try’ và ‘catch’ Blocks (tt)
Để bắt bất kỳ loại biệt lệ nào, ta phải chỉ ra kiểu biệt lệ là
‘Exception’
catch(Exception e)
Khi biệt lệ bị bắt không biết thuộc kiểu nào, chúng ta có thể sử dụng
lớp ‘Exception’ để bắt biệt lệ đó.
Lỗi sẽ được truyền thông qua khối lệnh ‘try catch’ cho tới khi chúng
bắt gặp một ‘catch’ tham chiếu tới nó, hoặc chương trình sẽ bị kết
thúc
20
Zero.java
public class Zero
{
public static void main (String[] args)
{
try{
int tu = 10;
int mau = 0;
System.out.println (tu / mau);
System.out.println ("This text will not be printed.");
}
catch (ArithmeticException e1){
System.out.println (“Không thể chia cho 0”);
}
catch (Exception e2){
System.out.println (“Lỗi ngoại lệ”);
}
}
}
21
ArrayDemo.java
public class ArrayDemo
{
public static void main (String[] args)
{
try {
int[] codes = new int[10];
for (int i=0; i <= 10; i++)
codes[i] = codes[i] * 2;
System.out.println ("This text will not be printed.");
}
catch (ArrayIndexOutOfBoundsException ex1) {
System.out.println (“Chỉ số truy xuất vượt quá kích
thước mảng”);
}
catch (Exception ex2) {
System.out.println (“Lỗi ngoại lệ”);
}
}
} 22
Khối ‘finally’ (tt)
Là tùy chọn không bắt buộc
Được đặt sau khối ‘catch’
Khối ‘finally’ bảo đảm lúc nào cũng được thực hiện bất chấp biệt lệ có
xảy ra hay không.
Nếu không có biệt lệ nào được phát sinh, những câu lệnh trong khối
finally được thực thi sau khi những câu lệnh trong khối try hoàn thành.
Nếu có biệt lệ phát sinh, những câu lệnh trong khối finally được thực thi
sau khi những câu lệnh trong khối catch tương ứng hoàn thành.
23
Ví dụ
import java.util.Scanner;
class FinallyDemo{
public static void main (String args[]){
String name;
int no1, no2;
try {
Scanner sc = new Scanner (System.in);
name = new String("Aptech Limited");
System.out.print("Input No1: ");
no1 = sc.nextInt();
System.out.print("Input No2: ");
no2 = sc.nextInt();
System.out.println(name);
System.out.println("Division Result is: " + no1/no2);
}
catch (ArithmeticException i) {
System.out.println("Cannot Divide by zero");
}
finally {
name = null; // clean up code
System.out.println(“Have good fun");
}
}
}
24
Bài tập
Viết chương trình cho phép nhập vào 1 số nguyên từ bàn
phím. Chương trình phải được xử lý trường hợp người dùng
nhập vào một số không phải số nguyên và yêu cầu nhập lại
cho đến khi nhập giá trị hợp lệ thì kết thúc.
25
Các biệt lệ được định nghĩa với lệnh ‘throw’ và ‘throws’
Các biệt lệ có thể được chặn với sự trợ giúp của từ khóa ‘throw’
Từ khóa ‘throw’ chỉ ra một biệt lệ vừa xảy ra.
Exceptions được đưa ra sử dụng lệnh throw
Thông thường lệnh throw được thực hiện bên trong lệnh if để đánh giá một điều kiện xem
liệu exception có được ném ra hay không
if ( some problem ) throw new
Exception("Informative Message" ) ;
Ví dụ của lệnh ‘throw’
try{
if (flag < 0)
{
throw new MyException( ) ; // user-defined
}
}
throw exceptionReference; hoặc
throw new ExceptionType();
26
Các biệt lệ được định nghĩa với lệnh ‘throw’ và ‘throws’
Một phương thức đơn có thể chặn nhiều hơn một biệt lệ
Ví dụ từ khóa ‘throws’ xử lý nhiều biệt lệ
public class Example {
public void exceptionExample( ) throws
ExException,LookupException {
try
{ // statements }
catch(ExException exmp)
{ …. }
catch(LookupException lkpex)
{ …. } } }
27
Lan truyền lỗi
Exception propagation
Lỗi lan truyền từ trong ra cho đến khi gặp bẫy lỗi hoặc tới main và
ứng dụng bị ngưng.
A()
B()
C()
D() Exception
Chiều gọi hàm
Chiều lan truyền lỗi
catch(...)
28
Ví dụ - Propagation.java
public class Propagation
{
public static void main (String[] args)
{
ExceptionScope demo = new ExceptionScope();
System.out.println("Program beginning.");
demo.level1();
System.out.println("Program ending.");
}
}
29
ExceptionScope.java
public class ExceptionScope
{
public void level1()
{
System.out.println("Level 1 beginning.");
try {
level2();
}
catch (ArithmeticException er)
{
System.out.println ();
System.out.println ("The exception message
is: " + er.getMessage());
System.out.println ();
System.out.println ("The call stack trace:");
er.printStackTrace();
System.out.println ();
}
System.out.println("Level 1 ending.");
}
public void level2()
{
System.out.println("Level 2 beginning.");
level3 ();
System.out.println("Level 2 ending.");
}
public void level3 ()
{
int numerator = 10, denominator = 0;
System.out.println("Level 3 beginning.");
int result = numerator / denominator;
System.out.println("Level 3 ending.");
}
}
30
Output
31
Xuất Exception
Exception thường do JVM xuất ra.
Code chương trình có thể chủ động xuất ra 1 đối tượng exception
bằng từ khóa throws, throw
Mức hành vi: dùng chỉ thị throws để báo cho JVM xuất một loại
Exception khi có lỗi.
Nếu là code trong hành vi thì dùng chỉ thị throw.
Khi throw trong code của thân hàm, phải yêu cầu tạo đối tượng
Exception bằng toán tử new.
Đương nhiên khi chủ động xuất lỗi, chương trình sẽ ngắt ngay.
32
Xuất Exception tại khai báo method
33
Xuất Exception trong thân method
gán message
cho Exception
34
Tự định nghĩa Exception
Những exception đã xây dựng trước có thể không đủ để bẫy tất cả
các lỗi, do đó người lập trình có thể tự định nghĩa một loại Exception
dựa trên các loại Exception đã có.
Khi định nghĩa những lớp exception riêng thì tất cả các exception
phải là lớp con của lớp Throwable.
Phương pháp khi khai báo một user-defined exception:
Tên lớp exception
Tên lớp cha
Thông báo lỗi.
35
myException.java
public class myException extends Exception
{
public myException ()
{
super ("Gia tri nhap vao khong nam trong khoang quy dinh.");
}
}
36
Main.java
Import java.util.*;
public class Main{
public static void main (String[] args)
{
try{
final int MIN = 25, MAX = 40;
myException er = new myException();
System.out.print ("Enter an integer value between " + MIN + " and " +
MAX + ", inclusive: ");
Scanner sc = new Scanner(System.in);
int value = sc.nextInt();
if (value MAX)
throw er;
else
System.out.println ("Gia tri nhap hop le");
}
catch (myException ex) {
System.out.println (ex.getMessage());
}
}
}
37
UserDefinedException.java
class ArraySizeException extends NegativeArraySizeException
{
public ArraySizeException() // constructor
{
super("You have passed illegal array size");
}
}
class UserDefinedException
{
int size, array[];
public UserDefinedException(int val)
{
size = val;
try
{
checkSize();
}
catch(ArraySizeException e)
{
System.out.println(e);
}
}
void checkSize() throws ArraySizeException
{
if(size < 0)
throw new ArraySizeException();
array = new int[3];
for(int count = 0; count < 3; count++)
array[count] = count+1;
}
public static void main(String arg[])
{
new UserDefinedException(Integer.parseInt(arg[0]));
}
}
Output 38
LUỒNG NHẬP XUẤT
(Input/Output Stream)
39
Nội dung
Tổng quan về I/O Stream
Đọc và ghi files text
Object serialization
40
Luồng nhập xuất - I/O Streams
Luồng là những đường ống dẫn cho phép gửi và nhận thông tin
trong những chương trình java
Khi một luồng được đọc hoặc ghi, những tiểu trình khác bị khóa
Một IOException được đưa ra, nếu như trong khi đọc và ghi luồng
xuất hiện lỗi.
Lớp ‘java.lang.System’ định nghĩa những luồng nhập xuất
chuẩn.
Một stream là một dãy những byte chảy từ source (nguồn) tới
destination (đích).
Trong một chương trình, chúng ta đọc thông tin từ một luồng nhập
(input stream) và ghi thông tin tới luồng xuất (output
stream
Đặt trong gói java.io
41
Luồng nhập xuất - I/O Streams
Input Streams – đọc dữ liệu từ nguồn như là Files, Buffers
trong bộ nhớ, và các Socket
Output Streams – ghi dữ liệu xuống đích như là Files, Buffers
trong bộ nhớ, và các Socket
42
Luồng nhập xuất chuẩn
Những lớp trong gói I/O chia luồng nhập xuất ra thành những loại khác
nhau
Một I/O stream là một
character stream: làm việc với dữ liệu text
byte stream: làm việc với dữ liệu byte
Có 3 loại I/O streams chuẩn:
standard output – được định nghĩa bởi đối tượng System.out
standard input – được định nghĩa bởi đối tượng System.in
standard error – được định nghĩa bởi đối tượng System.err
System.out được sử dụng khi chúng ta thực thi những câu lệnh
println để hiển thị kết quả trên màn hình.
System.in luồng nhập chuẩn thường được dùng để đọc các ký tự dữ liệu
từ bàn phím, luồng nhập chuẩn này có thể được sử dụng nhiều lần cùng
với đối tượng Scanner.
System.err là luồng lỗi chuẩn
43
Luồng nhập xuất chuẩn
Lớp System.out
System.out.println(“Hello”);
Lớp I/O khai báo luồng nhập như sau:
InputStreamReader isr=new InputStreamReader (System.in)
BufferedReader stdin = new BufferedReader (isr);
Đối tượng InputStreamReader chuyển luồng byte gốc
thành luồng ký tự.
Đối tượng BufferedReader cho phép chúng ta sử dụng
phương thức readLine để lấy toàn bộ dòng nhập.
44
Streams (cont.)
Đọc từ luồng
1. Mở luồng
2. Trong khi còn thông tin
3. Đọc luồng
4. Đóng luồng
Ghi xuống luồng
1. Đọc luồng
2. Trong khi còn thông tin
3. Ghi luồng
4. Đóng luồng
45
Các loại luồng nhập xuất
Luồng nhập xuất dựa trên những kiểu dữ liệu
Luồng ký tự
• Sử dụng để đọc và ghi ký tự
• Dựa trên dữ liệu 2 byte(16bits)
• xử lý thông qua những luồng
(Reader) đọc, (Writer) ghi.
• có thể xử lý những ký tự
Unicode
Luồng byte
• Dựa trên dữ liệu 1 byte (8 bit)
• có thể được sử dụng với bất kỳ
kiểu đối tượng nào
• Không thể xử lý các ký tự
UNICODE
• Sử dụng được cho byte và
luồng nhị phân
• Xử lý thông qua InputStreams
và OutputStreams
46
Cấu trúc phân cấp luồng nhập I/O
47
Cấu trúc phân cấp luồng nhập I/O
48
Biệt lệ (Exception) trong I/O
FileNotFoundException được đưa ra nếu như không tìm thấy
file (khi constructor FileReader được thực thi)
Thao tác trên một số lớp I/O có thể đưa ra IOException
File không tồn tại.
Nếu file đã tồn tại, nhưng chương trình không thể tìm thấy
nó.
File có thể không chứa kiểu dữ liệu chúng ta mong đợi.
Một IOException là một loại biệt lệ được kiểm tra.
49
Text Files
Những biến và mảng chỉ là bộ nhớ tạm thời, nó sẽ mất trong
quá trình thu gom rác hoặc khi chương trình kết thúc.
File được sử dụng cho việc lưu trữ lâu dài, được gọi là dữ liệu
cố định.
Thông tin có thể được đọc từ file và được ghi đến file bằng
cách khai báo và sử dụng những luồng nhập xuất.
Lớp FileReader đại diện cho file nhập bao gồm dữ liệu kiểu
kí tự
Lớp FileWriter đại diện cho file xuất, được sử dụng để
xuất dữ liệu kí tự xuống file
50
Ghi xuống file text
1. Mở luồng
2. Ghi thông tin
3. Đóng luồng
FileWriter
BufferedWriter
51
Ghi xuống file text
2 constructors của lớp FileWriter hay sử dụng:
FileWriter(String fileName)
FileWriter(String fileName, boolean append)
Trong constructor thứ 2 có 1 tham số append. Nếu append là
true thì constructor sẽ mở file đang tồn tại và cho ghi mà
không hủy bỏ nội dung cũ. Nếu file không tồn tại, nó sẽ được
tạo.
Lớp BufferedWriter có:
Phương thức write : cho phép ghi nội dung xuống file
Phương thức newLine : cho phép ngắt 1 dòng
52
Ghi xuống file text
Lớp FileWriter : đại diện cho file xuất, nhưng chỉ hỗ trợ
thao tác trên dữ liệu nhỏ
Do đó, chúng ta dựa vào đối tượng PrintStream, và sử
dụng phương thức print và println.
Chúng ta xây dựng lớp đại diện cho file xuất bằng cách kết
hợp những lớp này một cách thích hợp.
Luồng xuất nên được đóng tường minh.
53
WriteFile.java
import java.io.*;
public class WriteFile
{
public static void main (String[] args) throws
IOException
{
FileWriter fw = new FileWriter ("Lop.txt");
BufferedWriter bw = new BufferedWriter (fw);
bw.write(“DHTH1 – Dai hoc Tin hoc 1");
bw.write(“DHHO1 – Dai hoc Hoa 1");
bw.write("CDTH7K - Cao dang tin hoc 7K");
bw.close();
}
}
54
WriteFile.java
import java.io.*;
public class WriteFile
{
public static void main (String[] args) throws
IOException
{
FileWriter fw = new FileWriter ("Lop.txt");
BufferedWriter bw = new BufferedWriter (fw);
PrintWriter outFile = new PrintWriter (bw);
outFile.println(" DHTH1 – Dai hoc Tin hoc 1 ");
outFile.println(" DHHO1 – Dai hoc Hoa 1 ");
outFile.println("CDTH7K - Cao dang tin hoc 7K");
outFile.close();
}
}
55
Đọc từ file text
1. Mở luồng
2. Đọc thông tin
3. Đóng luồng
FileReader
BufferedReader
56
Đọc từ file text
Lớp BufferedReader: cung cấp phương thức readLine,
phương thức này cho phép chúng ta đọc toàn bộ dòng ký tự
trong 1 thao tác.
Phương thức readLine trả về một chuỗi
Phương thức readLine trả về null khi không có sẵn giá trị
nhập.
Constructor cho lớp BufferedReader như sau:
BufferedReader( Reader in )
Constructor cho lớp FileReader như sau:
FileReader(String fileName)throws
FileNotFoundException
57
ReadFile.java
import java.io.*;
public class ReadFile
{
public static void main (String[] args)
{
String filename = “Lop.txt“, para;
try
{
FileReader fr = new FileReader
(filename);
BufferedReader br = new BufferedReader
(fr);
para = br.readLine();
while (para != null)
{
System.out.println (para);
para = br.readLine();
}
br.close();
}
DHTH1 – Dai hoc Tin hoc 1
DHHO1 – Dai hoc Hoa 1
CDTH7K - Cao dang tin hoc 7K
Lop.txt
catch (FileNotFoundException
exception)
{
System.out.println ("The
file " + filename
+ " was not found.");
}
catch (IOException exception)
{
System.out.println
(exception);
}
}
}
58
Đọc – Ghi file text (Unicode)
1. Mở luồng
2. Đọc thông tin
3. Đóng luồng
FileInputStream
InputStreamReader
BufferedReader
1. Mở luồng
2. Ghi thông tin
3. Đóng luồng
FileOutputStream
OutputStreamWriter
BufferedWriter
Ghi Đọc
59
WriteFile_Uni.java (Unicode)
import java.io.*;
public class WriteFile_Uni
{
public static void ma