Tài liệu Lập trình nâng cao với java: LẬP TRÌNH NÂNG CAO VỚI JAVA
(Advanced Java programming)
Bộ môn Công nghệ Phần mềm
Đại học SPKT Hưng Yên
Bài 1. Kế thừa và đa hình trong Java ............................................................................................................. 9
1.1. Đối tượng trong Java ..................................................................................................................... 9
1.2 Lớp trong Java ............................................................................................................................... 9
1.3 Phương thức trong Java .............................................................................................................. 11
1.4 Tạo một đối tượng trong Java .................................................................................................... 11
1.5 Truy cập các biến instance và các phương thức trong Java ........................................................ 12
1.6 Đối tượng vô danh (annonymous...
170 trang |
Chia sẻ: putihuynh11 | Lượt xem: 589 | Lượt tải: 0
Bạn đang xem trước 20 trang mẫu tài liệu Lập trình nâng cao với java, để tải tài liệu gốc về máy bạn click vào nút DOWNLOAD ở trên
LẬP TRÌNH NÂNG CAO VỚI JAVA
(Advanced Java programming)
Bộ môn Công nghệ Phần mềm
Đại học SPKT Hưng Yên
Bài 1. Kế thừa và đa hình trong Java ............................................................................................................. 9
1.1. Đối tượng trong Java ..................................................................................................................... 9
1.2 Lớp trong Java ............................................................................................................................... 9
1.3 Phương thức trong Java .............................................................................................................. 11
1.4 Tạo một đối tượng trong Java .................................................................................................... 11
1.5 Truy cập các biến instance và các phương thức trong Java ........................................................ 12
1.6 Đối tượng vô danh (annonymous) trong Java ............................................................................ 16
Bài 3: Xử lý ngoại lệ ..................................................................................................................................... 19
3.1 Exception là gì? ................................................................................................................................. 19
Cấp bậc exception trong Java ............................................................................................................. 20
Các phương thức của lớp Exceptions trong Java ................................................................................ 21
Các tình huống phổ biến mà Exception có thể xảy ra ......................................................................... 22
Các từ khóa để Xử lý ngoại lệ trong Java ............................................................................................ 23
3.2 Khối try trong Java ............................................................................................................................ 23
Cú pháp của khối try-catch trong Java ................................................................................................ 23
Cú pháp của khối try-finally trong Java ............................................................................................... 23
Khối catch trong Java .......................................................................................................................... 23
Vấn đề khi không có Exception Handling ............................................................................................ 23
Xử lý vấn đề trên bởi Exception Handling trong Java ......................................................................... 24
Chế độ làm việc nội tại của khối try-catch trong Java......................................................................... 24
Nhiều khối catch trong Java ................................................................................................................ 25
Lồng khối try trong Java ...................................................................................................................... 26
Tại sao sử dụng các khối try lồng nhau trong Java ............................................................................. 26
Ví dụ về các khối try lồng nhau trong Java .......................................................................................... 27
3.3 Sự sử dụng khối finally trong Java .................................................................................................... 28
Tình huống 1: ở đây exeption không xuất hiện .................................................................................. 28
Tình huống 2: exception xuất hiện và không được xử lý. ................................................................... 28
Tình huống 3: exception xảy ra và được xử lý. ................................................................................... 29
3.6 Phân biệt final, finally, và finalize trong Java .................................................................................... 29
Ví dụ final trong Java ........................................................................................................................... 30
Ví dụ finally trong Java ........................................................................................................................ 30
Ví dụ finalize trong Java ...................................................................................................................... 30
3.4 Từ khóa throw trong Java ................................................................................................................ 31
Ví dụ từ khóa throw trong Java ........................................................................................................... 31
Quá trình lan truyền Exception trong Java ......................................................................................... 31
3.5 Từ khóa throws trong Java ................................................................................................................ 32
Cú pháp của từ khóa throws trong Java ............................................................................................. 33
Ví dụ về throws trong Java .................................................................................................................. 33
Trường hợp 1: Bạn xử lý exception..................................................................................................... 34
Trường hợp 2: Bạn khai báo exception ............................................................................................... 35
A. Chương trình ví dụ nếu exception không xuất hiện ....................................................................... 35
B. Chương trình ví dụ nếu exception xuất hiện .................................................................................. 35
Phân biệt throw và throws trong Java ................................................................................................ 36
Ví dụ về throw trong Java ................................................................................................................... 37
Ví dụ về throws trong Java .................................................................................................................. 37
Ví dụ về throw và throws trong Java................................................................................................... 37
3.6 ExceptionHandling và Ghi đè phương thức trong Java .................................................................... 37
3.7. Custom Exception trong Java ........................................................................................................... 41
Bài 5. String ................................................................................................................................................. 43
5.1 String trong Java ................................................................................................................................ 43
Chuỗi trong Java là gì ......................................................................................................................... 43
Cách tạo đối tượng String trong Java .................................................................................................. 43
Sử dụng từ khóa new .......................................................................................................................... 44
Tạo các String được định dạng trong Java .......................................................................................... 45
5.2 Immutable String trong Java ............................................................................................................. 46
Tại sao đối tượng String là Immutable trong Java? ............................................................................ 47
5.3. So sánh chuỗi trong Java .................................................................................................................. 47
So sánh chuỗi bởi phương thức equals() trong Java ........................................................................... 47
So sánh chuỗi với toán tử == trong Java ............................................................................................. 48
So sánh chuỗi bởi phương thức compareTo() trong Java ................................................................... 49
5.4 Nối chuỗi trong Java .......................................................................................................................... 49
Nối chuỗi bởi toán tử + trong Java ...................................................................................................... 49
Nối chuỗi bởi phương thức concat() trong Java .................................................................................. 50
5.5 Chuỗi con trong Java ......................................................................................................................... 51
Ví dụ về chuỗi con trong Java ............................................................................................................. 51
5.6 Phương thức của lớp String trong Java ............................................................................................. 52
Phương thức toUpperCase() và toLowerCase() của lớp String trong Java ......................................... 52
Phương thức trim() của lớp String trong Java ..................................................................................... 53
Phương thức startWith() và endsWith() của lớp String trong Java ..................................................... 53
Phương thức charAt() của lớp String trong Java................................................................................. 53
Phương thức length() của lớp String trong Java ................................................................................. 53
Phương thức intern của lớp String trong Java ..................................................................................... 53
Phương thức valueOf() của lớp String trong Java............................................................................... 54
Phương thức replace() của lớp String trong Java ................................................................................ 54
5.7 Lớp StringBuffer trong Java............................................................................................................... 54
Các Constructor quan trọng của lớp StringBuffer trong Java ............................................................. 54
Các phương thức quan trọng của lớp StringBuffer trong Java ........................................................... 55
Chuỗi dạng mutable là gì? .................................................................................................................. 55
Phương thức append() của lớp StringBuffer trong Java ..................................................................... 55
Phương thức insert() của lớp StringBuffer trong Java ........................................................................ 56
Phương thức replace() của lớp StringBuffer trong Java ..................................................................... 56
Phương thức delete() của lớp StringBuffer trong Java ....................................................................... 57
Phương thức reverse() của lớp StringBuffer trong Java ..................................................................... 57
Phương thức capacity() của lớp StringBuffer trong Java .................................................................... 57
Phương thức ensureCapacity() của lớp StringBuffer trong Java ........................................................ 58
5.8 StringBuilder trong Java .................................................................................................................... 59
Các Constructor quan trọng của lớp StringBuilder trong Java ........................................................... 59
Các phương thức quan trọng của lớp StringBuffer trong Java ........................................................... 59
Phương thức append() của lớp StringBuffer trong Java ..................................................................... 60
Phương thức insert() của lớp StringBuffer trong Java ........................................................................ 61
Phương thức replace() của lớp StringBuffer trong Java ..................................................................... 61
Phương thức delete() của lớp StringBuffer trong Java ....................................................................... 61
Phương thức reverse() của lớp StringBuffer trong Java ..................................................................... 62
Phương thức capacity() của lớp StringBuffer trong Java .................................................................... 62
Phương thức ensureCapacity() của lớp StringBuffer trong Java ........................................................ 63
5.9 So sánh lớp String và StringBuffer trong Java ................................................................................... 64
Kiểm tra hiệu suất của lớp String và StringBuffer trong Java ............................................................ 64
Kiểm tra HashCode của lớp String và StringBuffer trong Java .......................................................... 66
5.10 So sánh lớp StringBuffer và StringBuilder trong Java ..................................................................... 67
Ví dụ về lớp StringBuffer trong Java .................................................................................................. 67
Ví dụ về lớp StringBuilder trong Java ................................................................................................ 67
Kiểm tra hiệu suất của lớp StringBuffer và StringBuilder trong Java ................................................ 68
Bài 7. Bài tập và thảo luận về Case study ATM (1) ...................................................................................... 70
7.1. Các yêu cầu của ATM ....................................................................................................................... 70
7.2. Cách xây dựng lớp và đối tượng ...................................................................................................... 71
1. Các thành phần trong bản vẽ Class ................................................................................................. 71
2. Relationship (Quan hệ) ................................................................................................................... 72
3. Cách xây dựng bản vẽ Class ........................................................................................................... 75
7.2. Phân tích theo mô hình hướng đối tượng ....................................................................................... 77
1. Đặc tả Class ..................................................................................................................................... 77
2. Sử dụng bản vẽ Class ...................................................................................................................... 78
3. Kết luận ........................................................................................................................................... 78
Bài 8. Thao tác tệp ...................................................................................................................................... 79
8.1 File và I/O trong Java ......................................................................................................................... 79
Byte Stream trong Java ....................................................................................................................... 79
Character Stream trong Java ............................................................................................................... 80
Standard Stream trong Java ................................................................................................................ 81
Đọc và Ghi File trong Java ................................................................................................................... 83
FileInputStream trong Java: ................................................................................................................ 83
FileOutputStream trong Java .............................................................................................................. 84
Ví dụ: ................................................................................................................................................... 85
Điều hướng file và I/O trong Java ....................................................................................................... 86
Thư mục trong Java ............................................................................................................................. 86
Tạo thư mục trong Java ...................................................................................................................... 87
Liệt kê thư mục trong Java .................................................................................................................. 87
8.2 Lớp File trong Java ............................................................................................................................ 88
Ví dụ .................................................................................................................................................... 92
8.3 Lớp FileReader trong Java ................................................................................................................. 94
8.4 Lớp FileWriter trong Java .................................................................................................................. 95
Ví dụ .................................................................................................................................................... 96
Bài 10. Kiểu Collections ............................................................................................................................... 98
10.1 Collection trong Java .................................................................................................................... 98
Collection Interface trong Java ........................................................................................................... 98
Các lớp Collection trong Java .............................................................................................................. 99
Các thuật toán Collection trong Java ................................................................................................ 102
Cách sử dụng một Iterator trong Java .............................................................................................. 102
Cách sử dụng một Comparator trong Java ....................................................................................... 102
Tổng kết ............................................................................................................................................ 103
10.2 Collection Interface trong Java .................................................................................................. 103
Ví dụ .................................................................................................................................................. 105
10.3 List Interface trong Java ............................................................................................................. 106
Ví dụ .................................................................................................................................................. 108
10.4 Lớp LinkedList trong Java ........................................................................................................... 109
Ví dụ .................................................................................................................................................. 112
Ví dụ .................................................................................................................................................. 116
10.5 Lớp Hashtable trong Java .............................................................................................................. 117
Ví dụ .................................................................................................................................................. 119
10.6 Map Interface trong Java .............................................................................................................. 120
Ví dụ .................................................................................................................................................. 122
10.7 Lớp HashMap trong Java ............................................................................................................... 123
Ví dụ .................................................................................................................................................. 125
Bài 12 Generic trong Java .......................................................................................................................... 127
12.1 Generic trong Java ........................................................................................................................ 127
12.2 Các phương thức generic trong Java ............................................................................................ 127
Ví dụ: ................................................................................................................................................. 128
12.3 Các tham số kiểu giới hạn (bounded type) trong Java .................................................................. 129
Ví dụ: ................................................................................................................................................. 129
12.4 Các lớp Generic trong Java ............................................................................................................ 131
Ví dụ: ................................................................................................................................................. 131
Bài 14: Thread ........................................................................................................................................... 133
14.1 Thread trong Java .......................................................................................................................... 133
14.2 Vòng đời của một Thread trong Java ............................................................................................ 133
14.3 Quyền ưu tiên của thread trong Java ........................................................................................... 134
14.4 Tạo thread bởi triển khai Runnable Interface trong Java ............................................................. 134
Ví dụ: ................................................................................................................................................. 135
14.5 Tạo Thread bởi kế thừa lớp Thread trong Java ............................................................................. 137
Ví dụ: ................................................................................................................................................. 137
14.6 Các phương thức của lớp Thread trong Java ................................................................................ 139
Bài 17. Lập trình với JDBC ...................................................................................................................... 145
17.1 JDBC là gì? ................................................................................................................................... 145
Tại sao sử dụng JDBC? ..................................................................................................................... 145
API là gì? .......................................................................................................................................... 145
Các thành phần của JDBC ................................................................................................................ 145
17.2. Cài đặt JDBC ............................................................................................................................... 146
17.3 Giới thiệu JDBC Driver ............................................................................................................... 146
JDBC Driver là gì? ............................................................................................................................ 146
Giới thiệu JDBC-ODBC bridge driver ............................................................................................. 147
Giới thiệu Native-API driver ............................................................................................................ 147
Giới thiệu Network Protocol driver .................................................................................................. 147
Giới thiệu Thin driver ....................................................................................................................... 147
Sự sử dụng của các kiểu driver ......................................................................................................... 147
17.4 Kiểu dữ liệu trong JDBC .............................................................................................................. 148
Kiểu dữ liệu Date và Time trong JDBC ............................................................................................ 151
Xử lý giá trị NULL trong JDBC ....................................................................................................... 153
17.5 Kết nối JDBC với cơ sở dữ liệu .................................................................................................... 154
Sử dụng phương thức Class.forName() ............................................................................................ 155
Sử dụng DriverManager.registerDriver() .......................................................................................... 155
Đóng kết nối JDBC ........................................................................................................................... 158
Bài 18. Bài tập và thảo luận về Case study ATM (3) .................................................................................. 159
18.1. Cài đặt các chức năng và giao diện .............................................................................................. 159
18.2. Chạy và kiểm tra lỗi ...................................................................................................................... 159
Bài 20. Bài tập và thảo luận tổng kết môn học ......................................................................................... 160
20.1. Những ưu điểm của lập trình hướng đối tượng ............................................................................ 160
20.2. Phân tích bài toán theo mô hình hướng đối tượng ..................................................................... 160
Đối tượng trong Java ......................................................................................................................... 160
Lớp trong Java ................................................................................................................................... 161
Cú pháp để khai báo một lớp ............................................................................................................ 161
Ví dụ đơn giản về Lớp và Đối tượng trong Java ................................................................................ 161
Phương thức trong Java .................................................................................................................... 162
Constructor trong Java: ..................................................................................................................... 162
Tạo một đối tượng trong Java: ......................................................................................................... 163
Truy cập các biến instance và các phương thức trong Java .............................................................. 164
Ví dụ: ................................................................................................................................................. 164
Ví dụ đối tượng và lớp mà duy trì bản ghi các sinh viên ................................................................... 165
Ví dụ khác về lớp và đối tượng trong Java ........................................................................................ 166
Các cách khác nhau để tạo đối tượng trong Java? ........................................................................... 167
Đối tượng vô danh (annonymous) trong Java .................................................................................. 168
Tạo nhiều đối tượng bởi chỉ một kiểu .............................................................................................. 168
20.3. Trao đổi: ....................................................................................................................................... 169
Bài 1. Kế thừa và đa hình trong Java
1.1. Đối tượng trong Java
Đó là một thực thể có trạng thái và hành vi, ví dụ như bàn, ghế, xe con, mèo, Nó có
thể mang tính vật lý hoặc logic. Ví dụ về logic đó là Banking system.
Một đối tượng có ba đặc trưng sau:
Trạng thái: biểu diễn dữ liệu (giá trị) của một đối tượng.
Hành vi: biểu diễn hành vi (tính năng) của một đối tượng như gửi tiền vào, rút tiền ra,
Nhận diện: việc nhận diện đối tượng được triển khai thông qua một ID duy nhất. Giá trị
của ID là không thể nhìn thấy với người dùng bên ngoài. Nhưng nó được sử dụng nội tại
bởi JVM để nhận diện mỗi đối tượng một cách duy nhất.
Ví dụ: Bút là một đối tượng. Nó có tên là Thiên Long, có màu trắng, được xem như là
trạng thái của nó. Nó được sử dụng để viết, do đó viết là hành vi của nó.
Đối tượng là sự thể hiện (Instance) của một lớp. Lớp là một Template hoặc bản thiết kế
từ đó đối tượng được tạo. Vì thế đối tượng là Instance (kết quả) của một lớp.
1.2 Lớp trong Java
Một lớp là một nhóm các đối tượng mà có các thuộc tính chung. Lớp là một Template
hoặc bản thiết kế từ đó đối tượng được tạo. Một lớp trong Java có thể bao gồm:
Thành viên dữ liệu
Phương thức
Constructor
Block
Lớp và Interface
Cú pháp để khai báo một lớp
class ten_lop{
thanh_vien_du_lieu;
phuong_thuc;
}
Ví dụ đơn giản về Lớp và Đối tượng trong Java
Trong ví dụ này, chúng ta tạo một lớp Student có hai thành viên dữ liệu là id và name.
Chúng ta đang tạo đối tượng của lớp Student bởi từ khóa new và in giá trị đối tượng.
class Student1{
int id; //thanh vien du lieu (cung la bien instance)
String name; //thanh vien du lieu (cung la bien instance)
public static void main(String args[]){
Student1 s1=new Student1(); //tao mot doi tuong Student
System.out.println(s1.id);
System.out.println(s1.name);
}
}
Một lớp có thể chứa bất kỳ loại biến sau:
Biến Local: Các biến được định nghĩa bên trong các phương thức, constructor hoặc
block code được gọi là biến Local. Biến này sẽ được khai báo và khởi tạo bên trong
phương thức và biến này sẽ bị hủy khi phương thức đã hoàn thành.
Biến Instance: Các biến instance là các biến trong một lớp nhưng ở bên ngoài bất kỳ
phương thức nào. Những biến này được khởi tạo khi lớp này được tải. Các biến instance
có thể được truy cập từ bên trong bất kỳ phương thức, constructor hoặc khối nào của lớp
cụ thể đó.
Biến Class: Các biến class là các biến được khai báo với một lớp, bên ngoài bất kỳ
phương thức nào, với từ khóa static.
1.3 Phương thức trong Java
Trong Java, một phương thức là khá giống hàm, được sử dụng để trưng bày hành vi của một đối tượng.
Phương thức giúp code tăng tính tái sử dụng và tối ưu hóa code.
Từ khóa new được sử dụng để cấp phát bộ nhớ tại runtime.
Constructor trong Java:
Khi bàn luận về các lớp, một trong những chủ đề quan trọng là các constructor. Mỗi lớp có một constructor.
Nếu chúng ta không viết một constructor một cách rõ ràng cho một lớp thì bộ biên dịch Java xây dựng một
constructor mặc định cho lớp đó.
Mỗi khi một đối tượng mới được tạo ra, ít nhất một constructor sẽ được gọi. Quy tắc
chính của các constructor là chúng có cùng tên như lớp đó. Một lớp có thể có nhiều hơn
một constructor.
Sau đây là ví dụ về một constructor:
public class Xecon{
public Xecon(){
}
public Xecon(String ten){
// Contructor nay co mot tham so la ten.
}
}
Java cũng hỗ trợ Lớp Singleton trong Java, ở đây bạn sẽ có thể tạo chỉ một instance của
một lớp.
1.4 Tạo một đối tượng trong Java
Như đã đề cập trước đó, một lớp cung cấp bản thiết kế cho các đối tượng. Vì thế, về cơ
bản, một đối tượng được tạo từ một lớp. Trong Java, từ khóa new được sử dụng để tạo
một đối tượng mới.
Có ba bước khi tạo một đối tượng từ một lớp:
Khai báo: Một khai báo biến với một tên biến với một loại đối tượng.
Cài đặt: Từ khóa new được sử dụng để tạo đối tượng
Khởi tạo: Từ khóa new được theo sau bởi một lời gọi một constructor. Gọi hàm này khởi
tạo đối tượng mới.
Dưới đây là ví dụ về tạo một đối tượng:
public class Xecon{
public Xecon(String ten){
// Contructor nay co mot tham so la ten.
System.out.println("Ten xe la :" + ten );
}
public static void main(String []args){
// Lenh sau se tao mot doi tuong la Xecuatoi
Xecon Xecuatoi = new Xecon( "Toyota" );
}
}
Nếu chúng ta biên dịch và chạy chương trình, nó sẽ cho kết quả sau:
Ten xe la :Toyota
1.5 Truy cập các biến instance và các phương thức trong Java
Các biến instance và các phương thức được truy cập thông qua các đối tượng được tạo.
Để truy cập một biến instance, path sẽ là như sau:
/* Dau tien, ban tao mot doi tuong */
Doituongthamchieu = new Constructor();
/* Sau do ban goi mot bien nhu sau */
Doituongthamchieu.TenBien;
/* Bay gio ban co the goi mot phuong thuc lop nhu sau */
Doituongthamchieu.TenPhuongThuc();
Ví dụ:
Ví dụ này giải thích cách để truy cập các biến instance và các phương thức của một lớp:
public class Xecon{
int Giaxe;
public Xecon(String ten){
// Contructor nay co mot tham so la ten.
System.out.println("Ten xe la :" + ten );
}
public void setGia( int gia ){
Giaxe = gia;
}
public int getGia( ){
System.out.println("Gia mua xe la :" + Giaxe );
return Giaxe;
}
public static void main(String []args){
/* Tao doi tuong */
Xecon Xecuatoi = new Xecon( "Toyota" );
/* Goi mot phuong thuc lop de thiet lap gia xe */
Xecuatoi.setGia( 1000000000 );
/* Goi mot phuong thuc lop khac de lay gia xe */
Xecuatoi.getGia( );
/* Ban cung co the truy cap bien instance nhu sau */
System.out.println("Gia tri bien :" + Xecuatoi.Giaxe );
}
}
Biên dịch và thực thi chương trình sẽ cho kết quả sau:
Ten xe la :Toyota
Gia mua xe la :1000000000
Gia tri bien :1000000000
Ví dụ đối tượng và lớp mà duy trì bản ghi các sinh viên
Trong ví dụ này, chúng ta tạo hai đối tượng của lớp Student và khởi tạo giá trị của các đối
tượng này bằng việc triệu hồi phương thức insertRecord trên nó. Ở đây, chúng ta đang
hiển thị trạng thái (dữ liệu) của các đối tượng bằng việc triệu hồi phương thức
displayInformation.
class Student2{
int rollno;
String name;
void insertRecord(int r, String n){ //phuong thuc
rollno=r;
name=n;
}
void displayInformation(){System.out.println(rollno+" "+name);} //phuong thuc
public static void main(String args[]){
Student2 s1=new Student2();
Student2 s2=new Student2();
s1.insertRecord(111,"HoangThanh");
s2.insertRecord(222,"ThanhHuong");
s1.displayInformation();
s2.displayInformation();
}
}
Ví dụ khác về lớp và đối tượng trong Java
Ví dụ khác duy trì các bản ghi của lớp Rectangle. Phần giải thích tương tự như trên:
class Rectangle{
int length;
int width;
void insert(int l,int w){
length=l;
width=w;
}
void calculateArea(){System.out.println(length*width);}
public static void main(String args[]){
Rectangle r1=new Rectangle();
Rectangle r2=new Rectangle();
r1.insert(11,5);
r2.insert(3,15);
r1.calculateArea();
r2.calculateArea();
}
}
Các cách khác nhau để tạo đối tượng trong Java?
Có nhiều cách để tạo một đối tượng trong Java. Đó là:
Bằng từ khóa new
Bằng phương thức newInstance()
Bằng phương thức clone(), .
Bằng phương thức factory, ...
1.6 Đối tượng vô danh (annonymous) trong Java
Vô danh hiểu đơn giản là không có tên. Một đối tượng mà không có tham chiếu thì được
xem như là đối tượng vô danh. Nếu bạn phải sử dụng một đối tượng chỉ một lần, thì đối
tượng vô danh là một hướng tiếp cận tốt.
class Calculation{
void fact(int n){
int fact=1;
for(int i=1;i<=n;i++){
fact=fact*i;
}
System.out.println("factorial is "+fact);
}
public static void main(String args[]){
new Calculation().fact(5); //Goi phuong thuc voi doi tuong vo danh (annonymous)
}
}
Tạo nhiều đối tượng bởi chỉ một kiểu
Chúng ta có thể tạo nhiều đối tượng bởi chỉ một kiểu như khi chúng ta thực hiện trong
các kiểu gốc. Ví dụ:
Rectangle r1=new Rectangle(),r2=new Rectangle(); //Tao hai doi tuong
Ví dụ:
class Rectangle{
int length;
int width;
void insert(int l,int w){
length=l;
width=w;
}
void calculateArea(){System.out.println(length*width);}
public static void main(String args[]){
Rectangle r1=new Rectangle(),r2=new Rectangle(); //Tao hai doi tuong
r1.insert(11,5);
r2.insert(3,15);
r1.calculateArea();
r2.calculateArea();
}
}
Kết quả là:
Output:55
45
Bài 3: Xử lý ngoại lệ
3.1 Exception là gì?
Ý nghĩa trong từ điển: Exception là một tình trạng bất thường. Trong Java, Exception là
một sự kiện mà phá vỡ luồng chuẩn của chương trình. Nó là một đối tượng mà được ném
tại Runtime. Một exception (ngoại lệ) trong Java là một vấn đề xảy ra trong quá trình
thực hiện của chương trình. Một ngoại lệ có thể xảy ra với nhiều lý do khác nhau, như
dưới đây:
Người dùng nhập dữ liệu không hợp lệ.
Một file cần được mở nhưng không thể tìm thấy.
Kết nối mạng bị ngắt trong quá trình thực hiện giao tiếp hoặc JVM hết bộ nhớ.
Để hiểu sâu hơn các khái niệm được trình bày trong chương này, mời bạn tham khảo loạt
bài: Ví dụ về Exception trong Java.
Một vài những ngoại lệ xảy ra bởi lỗi của người dùng, một số khác bởi lỗi của lập trình
viên và số khác nữa đến từ lỗi của nguồn dữ liệu vật lý.
Để hiểu về cách xử lý ngoại lệ trong Java, bạn cần phải hiểu những loại ngoại lệ như sau:
Checked Exception: Là ngoại lệ thường xảy ra do người dùng mà không thể lường trước
được bởi lập trình viên. Ví dụ, một file được mở, nhưng file đó không thể tìm thấy và
ngoại lệ xảy ra. Những ngoại lệ này không thể được bỏ qua trong quá trình biên dịch.
Checked Exception là các lớp mà kế thừa lớp Throwable ngoại trừ RuntimeException và
Error. Ví dụ như IOException, SQLException, Checked Exception được kiểm tra tại
thời gian biên dịch compile-time.
Unchecked Exception: Một ngoại lệ xảy ra ở runtime là ngoại lệ có thể tránh được bởi
lập trình viên. Unchecked Exception là các lớp kế thừa RuntimeException, ví dụ
ArithmaticException, NullPointerException, ArrayIndexOutOfBoundsException,
Unchecked Exception không được kiểm tra tại compile-time, thay vào đó chúng được
kiểm tra tại runtime.
Error: Nó không giống các exception, nhưng vấn đề xảy ra vượt quá tầm kiểm soát của
lập trình viên hay người dùng. Error được bỏ qua trong code của bạn vì bạn hiếm khi có
thể làm gì đó khi chương trình bị error. Ví dụ như OutOfMemoryError,
VirtualMachineError, AssertionError, Nó được bỏ qua trong quá trình Java biên dịch.
Xử lý ngoại lệ (Exception Handling) là một kỹ thuật để xử lý các Runtime Error như
ClassNotFound, IO, SQL, Remote, Lợi thế chính của xử lý ngoại lệ là để duy trì luồng
chuẩn của ứng dụng. Exception thường phá vỡ luồng chuẩn của ứng dụng, và đó là tại
sao chúng ta sử dụng Exception Handling. Bạn theo dõi tình huống sau:
statement 1;
statement 2;
statement 3;
statement 4;
statement 5;//exception xuat hien
statement 6;
statement 7;
statement 8;
statement 9;
statement 10;
Giả sử có 10 lệnh trong chương trình của bạn và xuất hiện một Exception tại lệnh 5, phần
còn lại của code sẽ không được thực thi (từ lệnh 6 tới lệnh 10). Nếu chúng ta thực hiện
Exception Handling, phần lệnh còn lại sẽ được thực thi. Đó là ý nghĩa của việc sử dụng
Exception Handling trong Java.
Cấp bậc exception trong Java
Tất cả các lớp exception đều là lớp con của lớp java.lang.Exception . Lớp exception là
lớp con của lớp Throwable. Một loại lớp exception khác là Error cũng là lớp con của lớp
Throwable.
Erros không thường được đặt bẫy bởi các chương trình Java. Error thường được tạo ra để
thể hiện lỗi trong môi trường runtime. Ví dụ: JVM hết bộ nhớ. Thông thường các chương
trình không thể khôi phục từ các lỗi.
Lớp Exception có hai lớp con chính là : IOException và RuntimeException.
Đây là danh sách các checked và unchecked exception phổ biến: Exception có sẵn trong
Java.
Các phương thức của lớp Exceptions trong Java
Dưới đây là danh sách các phương thức phố biến của lớp Throwable trong Java
STT Phương thức và Miêu tả
1 public String getMessage()
Trả về một message cụ thể về exception đã xảy ra. Message này được
khởi tạo bởi phương thức contructor của Throwable
2 public Throwable getCause()
Trả về nguyên nhân xảy ra exception biểu diễn bởi đối tượng
Throwable
3 public String toString()
Trả về tên của lớp và kết hợp với kết quả từ phương thức
getMessage()
4 public void printStackTrace()
In ra kết quả của phương thức toString cùng với stack trace đến
System.err
5 public StackTraceElement [] getStackTrace()
Trả về một mảng chứa mỗi phần tử trên stack trace. Phần tử tại chỉ
mục 0 biểu diễn phần trên cùng của Call Stack, và phần tử cuối cùng
trong mảng biểu diễn phương thức tại dưới cùng của Call Stack
6 public Throwable fillInStackTrace()
Fills the stack trace of this Throwable object with the current stack
trace, adding to any previous information in the stack trace.
Các tình huống phổ biến mà Exception có thể xảy ra
Dưới đây là một số tình huồng phổ biến mà Unchecked Exception có thể xảy ra:
Với ArithmaticException: xảy ra nếu bạn chia bất cứ số nào cho số 0.
int a=50/0;//ArithmeticException
Với NullPointerException: nếu bạn có giá trị null trong bất cứ biến nào, thì việc thực
hiện bất cứ hoat động nào bởi biến này làm xuất hiện kiểu exception này.
String s=null;
System.out.println(s.length());//NullPointerException
Với NumberFormatException: việc định dạng sai bất cứ giá trị nào, có thể gây ra loại
ngoại lệ này. Giả sử bạn có một biến string mà có các ký tự, thì việc chuyển đổi biến
thành này chữ số sẽ làm xuất hiện NumberFormatException.
String s="abc";
int i=Integer.parseInt(s);//NumberFormatException
Với ArrayIndexOutOfBoundsException: nếu bạn đang chèn bất cứ giá trị nào trong
một chỉ mục sai sẽ làm xuất hiện kiểu exception này.
int a[]=new int[5];
a[10]=50; //ArrayIndexOutOfBoundsException
Các từ khóa để Xử lý ngoại lệ trong Java
Có 5 từ khóa được sử dụng để Xử lý ngoại lệ trong Java, đó là:
try
catch
finally
throw
throws
3.2 Khối try trong Java
Khối try trong Java được sử dụng để bao quanh code mà có thể ném một Exception. Nó
phải được sử dụng bên trong phương thức. Khối try phải được theo sau bởi hoặc khối
catch hoặc khối finally.
Cú pháp của khối try-catch trong Java
try{
//code ma co the nem exception
}catch(Exception_class_Name ref){}
Cú pháp của khối try-finally trong Java
try{
//code ma co the nem exception
}finally{}
Khối catch trong Java
Khối catch trong Java được sử dụng để xử lý các Exception. Nó phải được sử dụng chỉ
sau khối try. Bạn có thể sử dụng nhiều khối catch với một khối try đơn.
Vấn đề khi không có Exception Handling
Chúng ta cùng tìm hiểu vấn đề nếu không sử dụng khối try-catch.
public class Testtrycatch1{
public static void main(String args[]){
int data=50/0;//co the nem exception
System.out.println("Phan code con lai...");
}
}
Chương trình sẽ cho kết quả sau:
Exception in thread "main" java.lang.ArithmeticException: / by zero
Như trong ví dụ trên, phần còn lại của code không được thực thi (trong ví dụ này là lệnh
in Phan code con lai không được in). Giả sử nếu có khoảng 100 dòng code sau
exception, thì tất cả các dòng code này sẽ không được thực thi.
Xử lý vấn đề trên bởi Exception Handling trong Java
Bây giờ, cùng ví dụ trên, chúng ta sử dụng khối try-catch để xử lý vấn đề trên.
public class Testtrycatch2{
public static void main(String args[]){
try{
int data=50/0;
}catch(ArithmeticException e){System.out.println(e);}
System.out.println("Phan code con lai...");
}
}
Chương trình sẽ cho kết quả sau:
java.lang.ArithmeticException: / by zero
Phan code con lai...
Lúc này, phần còn lại của code đã được thực thi.
Chế độ làm việc nội tại của khối try-catch trong Java
Đầu tiên, JVM kiểm tra xem exception đã được xử lý hay chưa. Nếu exception chưa được
xử lý, JVM cung cấp một Exception Handler mặc định, để thực hiện các tác vụ sau:
In ra miêu tả của exception đó.
In ra stack trace (cấu trúc thứ bậc của phương thức nơi mà exception xuất hiện).
Làm cho chương trình ngừng lại.
Nhưng nếu exception đã được xử lý bởi Lập trình viên, thì luồng chuẩn của ứng dụng
được duy trì (hay là phần còn lại của code được thực thi).
Nhiều khối catch trong Java
Nếu bạn phải thực hiện các tác vụ khác nhau mà có thể xảy ra các exception khác nhau,
bạn sử dụng nhiều khối catch trong Java. Bạn theo dõi ví dụ đơn giản sau:
public class TestMultiCatchBlock{
public static void main(String args[]){
try{
int a[]=new int[5];
a[5]=30/0;
}
catch(ArithmeticException e){System.out.println("Task1 duoc hoan thanh");}
catch(ArrayIndexOutOfBoundsException e){System.out.println("Task2 duoc hoan thanh");}
catch(Exception e){System.out.println("Task chung duoc hoan thanh");}
System.out.println("Phan code con lai...");
}
}
Chương trình sẽ cho kết quả sau:
Task1 duoc hoan thanh
Phan code con lai...
Qui tắc 1: Tại một thời điểm, chỉ một exception được xuất hiện và tại một thời điểm chỉ
có một khối catch được thực thi.
Qui tắc 2: Tất cả khối catch phải được sắp xếp từ cụ thể nhất tới chung nhất, ví dụ: việc
bắt ArithimeticExption phải ở trước việc bắt Exception.
class TestMultipleCatchBlock1{
public static void main(String args[]){
try{
int a[]=new int[5];
a[5]=30/0;
}
catch(Exception e){System.out.println("Task chung duoc hoan thanh");}
catch(ArithmeticException e){System.out.println("Task1 duoc hoan thanh");}
catch(ArrayIndexOutOfBoundsException e){System.out.println("Task2 duoc hoan thanh");}
System.out.println("Phan code con lai...");
}
}
Chạy chương trình trên sẽ cho một lỗi compile time error.
Lồng khối try trong Java
Việc một khối try bên trong một khối try khác thì được gọi là các khối try được lồng vào
nhau, hay là lồng các khối try trong Java.
Tại sao sử dụng các khối try lồng nhau trong Java
Đôi khi có một tình huống là một phần của một khối code có thể gây ra một lỗi và toàn
bộ khối lại có thể gây ra lỗi khác. Trong các tình huống đó, Exception Handler phải được
lồng vào nhau. Cú pháp:
....
try
{
lenh 1;
lenh 2;
try
{
lenh 1;
lenh 2;
}
catch(Exception e)
{
}
}
catch(Exception e)
{
}
....
Ví dụ về các khối try lồng nhau trong Java
class Excep6{
public static void main(String args[]){
try{
try{
System.out.println("Thuc hien phep chia");
int b =39/0;
}catch(ArithmeticException e){System.out.println(e);}
try{
int a[]=new int[5];
a[5]=4;
}catch(ArrayIndexOutOfBoundsException e){System.out.println(e);}
System.out.println("Lenh khac");
}catch(Exception e){System.out.println("Da xu ly");}
System.out.println("Luong chuan..");
}
}
Chương trình sẽ cho kết quả sau:
Thuc hien phep chia
java.lang.ArithmeticException: / by zero
java.lang.ArrayIndexOutOfBoundsException: 5
Lenh khac
Luong chuan..
Khối finally trong là một khối được sử dụng để thực thi các phần code quan trọng như
đóng kết nối, đóng stream, Khối finally luôn luôn được thực thi dù cho exception có
được xử lý hay không. Khối finally phải được theo sau bởi khối try hoặc khối catch.
Ghi chú: nếu bạn không xử lý ngoại lệ trước khi kết thúc chương trình, JVM sẽ thực thi
khối finally (nếu bạn không có).
3.3 Sự sử dụng khối finally trong Java
Bạn theo dõi các tình huống khác nhau mà khối try trong Java có thể được sử dụng.
Tình huống 1: ở đây exeption không xuất hiện
class TestFinallyBlock{
public static void main(String args[]){
try{
int data=25/5;
System.out.println(data);
}
catch(NullPointerException e){System.out.println(e);}
finally{System.out.println("Khoi finally luon luon duoc thuc thi");}
System.out.println("Phan code con lai...");
}
}
Chương trình trên sẽ cho kết quả:
5
Khoi finally luon luon duoc thuc thi
Phan code con lai...
Tình huống 2: exception xuất hiện và không được xử lý.
class TestFinallyBlock1{
public static void main(String args[]){
try{
int data=25/0;
System.out.println(data);
}
catch(NullPointerException e){System.out.println(e);}
finally{System.out.println("Khoi finally luon luon duoc thuc thi");}
System.out.println("Phan code con lai...");
}
}
Chương trình trên sẽ cho kết quả:
Khoi finally luon luon duoc thuc thi
Exception in thread "main" java.lang.ArithmeticException: / by zero
Tình huống 3: exception xảy ra và được xử lý.
public class TestFinallyBlock2{
public static void main(String args[]){
try{
int data=25/0;
System.out.println(data);
}
catch(ArithmeticException e){System.out.println(e);}
finally{System.out.println("Khoi finally luon luon duoc thuc thi");}
System.out.println("Phan code con lai...");
}
}
Chương trình trên sẽ cho kết quả:
java.lang.ArithmeticException: / by zero
Khoi finally luon luon duoc thuc thi
Phan code con lai...
Qui tắc: Với một khối try thì có thể có 0 hoặc nhiều khối catch, nhưng chỉ có một khối
finally.
Ghi chú: Khối finally sẽ không được thực thi nếu chương trình thoát ra (hoặc bởi gọi
System.exit() hoặc bởi gây ra một lỗi nghiêm trọng Fatal Error mà làm ngừng tiến trình).
3.6 Phân biệt final, finally, và finalize trong Java
Bảng dưới đây liệt kê và miêu tả các điểm khác nhau giữa final, finally và finalize trong Java:
final finally finalize
Final được sử dụng để áp dụng các ràng buộc trên
lớp, phương thức và biến. Lớp final không thể được
kế thừa, phương thức final không thể bị ghi đè, và
giá trị biến final không thể bị thay đổi
Finally được sử dụng để đặt
các code quan trọng, nó sẽ
được thực thi dù exception có
được xử lý hay không
Finalize được sử dụng để
thực hiện tiến trình dọn
sạch
Final là một từ khóa Finally là một khối Finalize là một phương
thức
Ví dụ final trong Java
class ViduFinal{
public static void main(String[] args){
final int x=100;
x=200;//Compile Time Error
}}
Ví dụ finally trong Java
class ViduFinally{
public static void main(String[] args){
try{
int x=300;
}catch(Exception e){System.out.println(e);}
finally{System.out.println("Khoi finally duoc thuc thi");}
}}
Ví dụ finalize trong Java
class ViduFinalize{
public void finalize(){System.out.println("finalize duoc goi");}
public static void main(String[] args){
ViduFinalize f1=new ViduFinalize();
ViduFinalize f2=new ViduFinalize();
f1=null;
f2=null;
System.gc();
}}
3.4 Từ khóa throw trong Java
Từ khóa throw trong Java được sử dụng để ném tường minh một exception. Chúng ta có
thể ném hoặc Checked Exception hoặc Unchecked Exception trong Java bởi từ khóa
throw. Từ khóa throw được sử dụng chủ yếu để ném các Custom Exception (là các
exception được định nghĩa bởi lập trình viên). Chúng ta sẽ tìm hiểu về Custom Exception
trong chương riêng.
Cú pháp của từ khóa throw trong Java như sau:
throw exception;
Cùng theo dõi ví dụ đơn giản để ném IOException:
throw new IOException("Xin loi: device error);
Ví dụ từ khóa throw trong Java
Trong ví dụ này, chúng ta đã tạo phương thức validate mà nhận giá trị nguyên như là một
tham số. Nếu tuoi là nhỏ hơn 18, chúng ta ném ArithmeticException, nếu không chúng ta
sẽ in một thông báo là: Chao mung ban den bo phieu.
public class TestThrow1{
static void validate(int tuoi){
if(tuoi<18)
throw new ArithmeticException("Khong hop le");
else
System.out.println("Chao mung ban den bo phieu");
}
public static void main(String args[]){
validate(13);
System.out.println("Phan code con lai...");
}
}
Chương trình Java trên sẽ cho kết quả:
Exception in thread "main" java.lang.ArithmeticException: Khong hop le
Quá trình lan truyền Exception trong Java
Đầu tiên, một exception được ném từ đầu Stack và nếu nó không được bắt, nó chuyển
xuống dưới Call Stack tới phương thức trước đó, nếu tại đây nó không được bắt, thì
exception lại di chuyển xuống dưới tới phương thức trước đó, tới khi nó được bắt hoặc
tới khi nó chạm đáy của Call Stack. Đây là quá trình làn truyền exception.
Qui tắc: Theo mặc định, Unchecked Exception được lan truyền trong Calling Chain.
Ví dụ về quá trình lan truyền của exception:
class TestExceptionPropagation1{
void m(){
int data=50/0;
}
void n(){
m();
}
void p(){
try{
n();
}catch(Exception e){System.out.println("Exception duoc xu ly");}
}
public static void main(String args[]){
TestExceptionPropagation1 obj=new TestExceptionPropagation1();
obj.p();
System.out.println("Luong chuan...");
}
}
3.5 Từ khóa throws trong Java
Từ khóa throws trong Java được sử dụng để khai báo một Exception. Nó cung cấp một
thông tin tới Lập trình viên rằng có thể xuất hiện một Exception, để họ nên cung cấp một
code để xử lý ngoại lệ để duy trì luồng chuẩn của chương trình.
Xử lý ngoại lệ (Exception Handling) chủ yếu được sử dụng để xử lý các Checked
Exception. Nếu có thể xuất hiện bất cứ Unchecked Exception nào chẳng hạn như
NullPointerException, thì đó là lỗi của lập trình viên vì họ đã không thực hiện kiểm tra
code trước khi sử dụng.
Cú pháp của từ khóa throws trong Java
kieu_tra_ve ten_phuong_thuc() throws ten_lop_exception{
//phan code cua phuong thuc
}
Câu hỏi: Kiểu Exception nên được khai báo?
Chỉ dành cho Checked Exception, bởi vì:
Unchecked Exception: dưới sự điều khiển của bạn bằng việc kiểm tra và sửa lỗi code.
Error: Vượt quá tầm kiểm soát của bạn, ví dụ: bạn không thể làm điều gì nếu xuất hiện
VirtualMachineError hoặc StackOverflowErrror.
Lợi thế của từ khóa throws trong Java
Bây giờ, bởi sử dụng từ khóa throws, các Checked Exception có thể được lan truyền
(trong Call Stack). Nó cung cấp thông tin tới người gọi phương thức về Exception đó.
Ví dụ về throws trong Java
Chương trình Java sau sử dụng từ khóa throws để minh họa việc Checked Exception có
thể được lan truyền (trong Call Stack).
import java.io.IOException;
class Testthrows1{
void m()throws IOException{
throw new IOException("device error");//checked exception
}
void n()throws IOException{
m();
}
void p(){
try{
n();
}catch(Exception e){System.out.println("Exception duoc xu ly");}
}
public static void main(String args[]){
Testthrows1 obj=new Testthrows1();
obj.p();
System.out.println("Luong chuan...");
}
}
Chương trình Java trên sẽ cho kết quả:
Exception duoc xu ly
Luong chuan...
Qui tắc: Nếu bạn đang gọi một phương thức mà khai báo một exception, bạn phải hoặc
bắt hoặc khai báo exception đó.
Có hai trường hợp:
Trường hợp 1: Bạn bắt exception (sử dụng try-catch để xử lý exception đó)
Trường hợp 2: Bạn khai báo exception (xác định từ khóa throws với phương thức đó)
Trường hợp 1: Bạn xử lý exception
Trong trường hợp này, code sẽ được thực thi tốt dù cho exception có xuất hiện trong chương trình hay không.
import java.io.*;
class M{
void method()throws IOException{
throw new IOException("device error");
}
}
public class Testthrows2{
public static void main(String args[]){
try{
M m=new M();
m.method();
}catch(Exception e){System.out.println("Exception duoc xu ly");}
System.out.println("Luong chuan...");
}
}
Chương trình Java trên sẽ cho kết quả:
Exception duoc xu ly
Luong chuan...
Trường hợp 2: Bạn khai báo exception
Nếu exception không xuất hiện, code sẽ được thực thi tốt.
Nếu exception xuất hiện, một exception sẽ được ném tại runtime bởi vì throws không xử
lý exception đó.
A. Chương trình ví dụ nếu exception không xuất hiện
import java.io.*;
class M{
void method()throws IOException{
System.out.println("Thiet bi hoat dong tot");
}
}
class Testthrows3{
public static void main(String args[])throws IOException{//Khai bao exception
M m=new M();
m.method();
System.out.println("Luong chuan...");
}
}
Chương trình Java trên sẽ cho kết quả:
Thiet bi hoat dong tot
Luong chuan...
B. Chương trình ví dụ nếu exception xuất hiện
import java.io.*;
class M{
void method()throws IOException{
throw new IOException("device error");
}
}
class Testthrows4{
public static void main(String args[])throws IOException{//Khai bao exception
M m=new M();
m.method();
System.out.println("Luong chuan...");
}
}
Chương trình Java trên sẽ cho Runtime Error.
Câu hỏi: Chúng ta có thể tái ném một exception không?
Có, bằng cách ném cùng exception đó trong khối catch.
Phân biệt throw và throws trong Java
Có nhiều điểm khác nhau giữa hai từ khóa throw và throws. Bảng dưới liệt kê các điểm
khác nhau này.
throw throws
Từ khóa throw được sử dụng để ném
tường minh một exception
Từ khóa throws được sử dụng để khai báo
một exception
Checked Exception không thể được lan
truyền chỉ bởi sử dụng throw
Checked Exception không thể được lan
truyền với throws
Throw được theo sau bởi một instance Throws được theo sau bởi một lớp
Throw được sử dụng bên trong một
phương thức
Throws được sử dụng với khai báo phương
thức
Bạn có thể ném nhiều exception Bạn có thể khai báo nhiều exception, ví dụ
public void phuong_thuc()throws
IOException,SQLException
Ví dụ về throw trong Java
void m(){
throw new ArithmeticException("sorry");
}
Ví dụ về throws trong Java
void m()throws ArithmeticException{
//Phan code cua phuong thuc
}
Ví dụ về throw và throws trong Java
void m()throws ArithmeticException{
throw new ArithmeticException("sorry");
}
3.6 ExceptionHandling và Ghi đè phương thức trong Java
Có một số qui tắc bạn nên biết khi nói đến ghi đè phương thức với xử lý ngoại lệ. Đó là:
Nếu phương thức của lớp cha không khai báo một exception: phương thức ghi đè của lớp
con không thể khai báo Checked Exception nhưng có thể khai báo Unchecked Exception.
Qui tắc 1: Nếu phương thức của lớp cha không khai báo một exception: phương thức ghi
đè của lớp con không thể khai báo Checked Exception.
import java.io.*;
class Parent{
void msg(){System.out.println("parent");}
}
class TestExceptionChild extends Parent{
void msg()throws IOException{
System.out.println("TestExceptionChild");
}
public static void main(String args[]){
Parent p=new TestExceptionChild();
p.msg();
}
}
Chạy chương trình sẽ cho Compile Time Error.
Qui tắc 2: Nếu phương thức của lớp cha không khai báo một exception: phương thức ghi
đè của lớp con không thể khai báo Checked Exception nhưng có thể khai báo Unchecked
Exception.
import java.io.*;
class Parent{
void msg(){System.out.println("parent");}
}
class TestExceptionChild1 extends Parent{
void msg()throws ArithmeticException{
System.out.println("child");
}
public static void main(String args[]){
Parent p=new TestExceptionChild1();
p.msg();
}
}
Chạy chương trình sẽ cho kết quả:
child
Nếu phương thức lớp cha khai báo một exception: phương thức ghi đè của lớp con có thể
khai báo cùng exception đó, exception của lớp con, hoặc không khai báo exception nào,
nhưng không thể khai báo exception cha.
1. Ví dụ trường hợp phương thức ghi đè của lớp con khai báo exception cha.
import java.io.*;
class Parent{
void msg()throws ArithmeticException{System.out.println("parent");}
}
class TestExceptionChild2 extends Parent{
void msg()throws Exception{System.out.println("child");}
public static void main(String args[]){
Parent p=new TestExceptionChild2();
try{
p.msg();
}catch(Exception e){}
}
}
Chạy chương trình sẽ cho Compile Time Error.
2. Ví dụ trường hợp phương thức ghi đè của lớp con khai báo cùng exception đó.
import java.io.*;
class Parent{
void msg()throws Exception{System.out.println("parent");}
}
class TestExceptionChild3 extends Parent{
void msg()throws Exception{System.out.println("child");}
public static void main(String args[]){
Parent p=new TestExceptionChild3();
try{
p.msg();
}catch(Exception e){}
}
}
Chạy chương trình sẽ cho kết quả:
child
3. Ví dụ trường hợp phương thức ghi đè của lớp con khai báo exception của lớp con.
import java.io.*;
class Parent{
void msg()throws Exception{System.out.println("parent");}
}
class TestExceptionChild4 extends Parent{
void msg()throws ArithmeticException{System.out.println("child");}
public static void main(String args[]){
Parent p=new TestExceptionChild4();
try{
p.msg();
}catch(Exception e){}
}
}
Chạy chương trình sẽ cho kết quả:
child
3. Ví dụ trường hợp phương thức ghi đè của lớp con không khai báo exception nào.
import java.io.*;
class Parent{
void msg()throws Exception{System.out.println("parent");}
}
class TestExceptionChild5 extends Parent{
void msg(){System.out.println("child");}
public static void main(String args[]){
Parent p=new TestExceptionChild5();
try{
p.msg();
}catch(Exception e){}
}
}
Chạy chương trình sẽ cho kết quả:
child
3.7. Custom Exception trong Java
Custom Exception là ngoại lệ do bạn tự định nghĩa hay bạn tự tạo riêng cho mình.
Custom Exception trong Java được sử dụng để tùy biến ngoại lệ theo yêu cầu của người
dùng. Bởi sự giúp đỡ của loại ngoại lệ này, bạn có thể có riêng kiểu và thông điệp ngoại
lệ cho mình.
Bạn theo dõi chương trình Java minh họa về Custom Exception sau:
class InvalidAgeException extends Exception{
InvalidAgeException(String s){
super(s);
}
}
-------------
class TestCustomException1{
static void validate(int age)throws InvalidAgeException{
if(age<18)
throw new InvalidAgeException("Khong hop le");
else
System.out.println("Chao mung ban toi bo phien");
}
public static void main(String args[]){
try{
validate(13);
}catch(Exception m){System.out.println("Exception xuat hien: "+m);}
System.out.println("Phan code con lai...");
}
}
Bài 5. String
5.1 String trong Java
[String(Chuỗi) trong Java- Xử lý chuỗi trong java]Chuỗi (String) trong Java cung cấp
nhiều khái niệm đa dạng giúp bạn thao tác và xử lý với chuỗi như so sánh, cắt, nối, tìm
độ dài, thay thế, tìm chuỗi con, . Trong Java, về cơ bản chuỗi là một đối tượng mà biểu
diễn dãy các giá trị char. Một mảng các ký tự làm việc khá giống như chuỗi trong Java.
Ví dụ:
char[] ch={'j','a','v','a','t','p','o','i','n','t'};
String s=new String(ch);
Là tương tự như:
String s="vietjack";
Lớp java.lang.String triển khai các Serializable, Comparable và CharSequence Interface.
Chuỗi (String) trong Java là không thể thay đổi (immutable), ví dụ: nó không thể bị thay
đổi nhưng sẽ có một instance được tạo. Tuy nhiên, nếu bạn muốn sử dụng các lớp mà có
thể thay đổi, bạn có thể lựa chọn sử dụng các lớp StringBuffer và StringBuilder
Chúng ta sẽ tìm hiểu về chuỗi dạng immutable sau. Ở chương này, chúng ta sẽ tìm hiểu
chuỗi trong Java là gì và cách để tạo đối tượng String.
Chuỗi trong Java là gì
Nói chung, chuỗi là một dãy ký tự liên tục. Trong Java, String là một đối tượng mà biểu
diễn một dãy ký tự liên tục. Lớp String được sử dụng để tạo đối tượng String.
Cách tạo đối tượng String trong Java
Có hai cách để tạo đối tượng String: bởi hằng chuỗi (string literal) và bởi từ khóa new.
Sử dụng String Literal
String Literal trong Java được tạo bởi sử dụng dấu trích dẫn kép. Ví dụ:
String s="xinchao";
Ghi chú: Các đối tượng String được lưu trữ trong một khu vực bộ nhớ đặc biệt gọi
là String Constant Pool.
Theo mặc định thì Java không lưu trữ tất cả đối tượng String vào String Pool. Thay vào
đó, họ cung cấp một cách thức linh hoạt cho việc lưu trữ bất kỳ một đối tượng nào trong
String Pool, sử dụng phương thức intern() để lưu trữ mọi object bất kỳ vào String pool.
Khi sử dụng String literal thì mặc định nó sẽ gọi phương thức intern() để làm việc này
giúp bạn. Đây chính là điểm khác biệt lớn nhất giữa String literal và sử dụng new.
Mỗi khi bạn tạo một hằng chuỗi, đầu tiên JVM kiểm tra Pool chứa các hằng chuỗi. Nếu
chuỗi đã tồn tại trong Pool, một tham chiếu tới Pool được trả về. Nếu chuỗi không tồn tại
trong Pool, một instance của chuỗi mới được tạo và được đặt trong Pool. Ví dụ:
String s1="xinchao";
String s2="xinchao";//se khong tao instance moi
Trong ví dụ trên chỉ có một đối tượng sẽ được tạo. Đầu tiên JVM sẽ không tìm thấy bất
cứ đối tượng String nào với giá trị "xinchao" trong Pool, vì thế nó sẽ tạo một đối tượng
mới. Sau đó, nó sẽ tìm thấy chuỗi với giá trị "xinchao" trong Pool, nó sẽ không tạo đối
tượng mới nhưng sẽ trả về tham chiếu tới cùng instance (sự thể hiện) của đối tượng đó.
Tại sao Java sử dụng khái niệm String Literal?
Để làm cho Java hiệu quả hơn trong việc sử dụng bộ nhớ bởi vì không có đối tượng mới
nào được tạo khi mà nếu nó đã tồn tại trong Pool.
Sử dụng từ khóa new
String s=new String("xinchao");//tao hai doi tuong va mot bien tham chieu
Trong trường hợp này, JVM sẽ tạo một đối tượng mới như bình thường trong bộ nhớ
Heap (không phải Pool) và hằng "xinchao" sẽ được đặt trong Pool. Biến sẽ tham chiếu tới
đối tượng trong Heap (chứ không là Pool).
Ví dụ về String trong Java
public class StringExample{
public static void main(String args[]){
String s1="java";//tao string boi string literal
char ch[]={'s','t','r','i','n','g','s'};
String s2=new String(ch);//chuyen doi mang ky tu thanh string
String s3=new String("Vidu");//tao string boi tu khoa new
System.out.println(s1);
System.out.println(s2);
System.out.println(s3);
}}
Tạo các String được định dạng trong Java
Bạn có các phương thức printf() và format() để in output với các số được định dạng. Lớp
String có một phương thức lớp tương đương, là format(), mà trả về một đối tượng String
chứ không là một đối tượng PrintStream.
Sử dụng phương thức static format() của đối tượng String cho phép bạn tạo một chuỗi đã
được định dạng để bạn có thể tái sử dụng, trái ngược với lệnh in một lần. Ví dụ, thay vì:
System.out.printf("Gia tri cua bien float la " +
"%f, trong khi gia tri cua bien integer " +
"bien la %d, va chuoi la " +
"is %s", floatVar, intVar, stringVar);
Bạn có thể viết:
String fs;
fs = String.format("Gia tri cua bien float la " +
"%f, trong khi gia tri cua bien integer " +
"bien la %d, va chuoi la " +
"is %s", floatVar, intVar, stringVar);
System.out.println(fs);
5.2 Immutable String trong Java
Trong Java, các đối tượng chuỗi là immutable. Immutable nghĩa là không thể thay đổi
hay không thể sửa đổi. Một khi đối tượng String đã được tạo thì dữ liệu hoặc trạng thái
của nó không thể bị thay đổi nhưng một đối tượng String được tạo. Bạn theo dõi ví dụ
sau để hiểu khái niệm Immutable trong Java:
class Testimmutablestring{
public static void main(String args[]){
String s="vietjack";
s.concat(" vietjackteam");//phuong thuc concat() phu them vao cuoi chuoi
System.out.println(s);//se in vietjack vi string la immutable
}
}
Ở đây, "vietjack" là không bị thay đổi nhưng một đối tượng mới được tạo với
"vietjackteam". Đó là tại sao String trong Java là không thể sửa đổi. Trong ví dụ trên, hai
đối tượng được tạo, nhưng biến tham chiếu vẫn tham chiếu tới "vietjack" chứ không tham
chiếu tới "vietjackteam".
Nhưng nếu chúng ta gán nó tới biến tham chiếu một cách tường minh, thì nó sẽ tham
chiếu tới đối tượng "vietjackteam". Ví dụ:
class Testimmutablestring1{
public static void main(String args[]){
String s="vietjack";
s=s.concat(" vietjackteam");
System.out.println(s);
}
}
Trong trường hợp này, s trỏ tới "vietjackteam". Bạn nên chú ý rằng đối tượng "vietjack"
vẫn không bị sửa đổi.
Tại sao đối tượng String là Immutable trong Java?
Bởi vì Java sử dụng khái niệm String Literal. Giả sử có 5 biến tham chiếu, tất cả tham
chiếu tới một đối tượng "vietjack". Nếu một biến tham chiếu thay đổi giá trị của đối
tượng, nó sẽ có tác động tới tất cả các biến tham chiếu khác. Đó là tại sao đối tượng
String là Immutable trong Java.
5.3. So sánh chuỗi trong Java
Chúng ta có thể so sánh chuỗi trong Java dựa trên cơ sở nội dung và tham chiếu. Nó được
sử dụng trong sự xác nhận bởi phương thức equal(), sắp xếp bởi phương thức
compareTo(), so khớp tham chiếu bởi toán tử ==,
So sánh chuỗi bởi phương thức equals() trong Java
Phương thức equals() so sánh nội dung ban đầu của chuỗi. Nó so sánh tính cân bằng của
các giá trị chuỗi. Lớp String cung cấp hai phương thức:
public boolean equals(Object khac) so sánh chuỗi này với object đã cho.
public boolean equalsIgnoreCase(String khac) so sánh chuỗi này với chuỗi khác, bỏ qua
sự khác biệt về kiểu.
Ví dụ 1
class Sosanhchuoi1{
public static void main(String args[]){
String s1="Vietjack";
String s2="Vietjack";
String s3=new String("Vietjack");
String s4="Vietjackteam";
System.out.println(s1.equals(s2));//true
System.out.println(s1.equals(s3));//true
System.out.println(s1.equals(s4));//false
}
}
Ví dụ 2
class Sosanhchuoi2{
public static void main(String args[]){
String s1="Vietjack";
String s2="VIETJACK";
System.out.println(s1.equals(s2));//false
System.out.println(s1.equalsIgnoreCase(s3));//true
}
}
So sánh chuỗi với toán tử == trong Java
Toán tử == trong Java so sánh các tham chiếu chứ không phải so sánh các giá trị. Ví dụ:
class Sosanhchuoi3{
public static void main(String args[]){
String s1="Vietjack";
String s2="Vietjack";
String s3=new String("Vietjack");
System.out.println(s1==s2);//true (boi vi ca hai cung tham chieu toi cung instance)
System.out.println(s1==s3);//false(boi vi s3 tham chieu toi instance duoc tao khong
phai trong Pool)
}
}
So sánh chuỗi bởi phương thức compareTo() trong Java
Phương thức compateTo() so sánh các giá trị theo từ điển và trả về một giá trị nguyên
miêu tả rằng nếu chuỗi đầu tiên là nhỏ hơn, bằng hoặc lớn hơn chuỗi thứ hai. Giả sử s1 và
s2 là hai chuỗi. Nếu:
s1 == s2 thì trả về 0.
s1 > s2 thì trả về giá trị dương
s1 < s2 thì trả về giá trị âm
class Teststringcomparison4{
public static void main(String args[]){
String s1="Vietjack";
String s2="Vietjack";
String s3="Doan";
System.out.println(s1.compareTo(s2));//0
System.out.println(s1.compareTo(s3));//1(boi vi s1 > s3)
System.out.println(s3.compareTo(s1));//-1(boi vi s3 < s1 )
}
}
5.4 Nối chuỗi trong Java
Trong Java, nối chuỗi tạo nên một chuỗi mới mà là chuỗi tổ hợp của nhiều chuỗi. Có hai
cách để nối chuỗi trong Java, đó là:
Bởi toán tử nối chuỗi +
Bởi phương thức concat()
Nối chuỗi bởi toán tử + trong Java
Toán tử + trong Java được sử dụng để nối hai chuỗi. Ví dụ:
class Noichuoi1{
public static void main(String args[]){
String s="Vietjack"+" Team";
System.out.println(s);//in ra ket qua Vietjack Team
}
}
Trình biên dịch Compiler chuyển đổi code trên thành dạng:
String s=(new StringBuilder()).append("Vietjack").append(" Team).toString();
Trong Java, nối chuỗi được thực hiện thông qua lớp StringBuilder (hoặc StringBuffer) và
phương thức append của nó. Toán tử nối chuỗi tạo một chuỗi mới bằng cách phụ thêm
toán hạng thứ hai vào phần cuối của toán hạng đầu tiên. Toán tử nối chuỗi không những
có thể nối chuỗi mà còn có thể nối các giá trị ở kiểu dữ liệu gốc. Ví dụ:
class Noichuoi2{
public static void main(String args[]){
String s=50+30+"Vietjack"+40+40;
System.out.println(s);//in ra ket qua 80Vietjack4040
}
}
Ghi chú: Sau một String Literal, tất cả toán tử + sẽ được đối xử như là toán tử nối chuỗi.
Nối chuỗi bởi phương thức concat() trong Java
Phương thức concat() trong Java nối chuỗi đã cho vào phần cuối của chuỗi hiện tại. Cú
pháp:
public String concat(String khac)
Bạn theo dõi ví dụ sau về phương thức concat():
class Noichuoi3{
public static void main(String args[]){
String s1="Vietjack ";
String s2="Team";
String s3=s1.concat(s2);
System.out.println(s3);//in ra ket qua Vietjack Team
}
}
5.5 Chuỗi con trong Java
Một phần của chuỗi được gọi là chuỗi con (substring, hay chuỗi phụ). Nói cách khác,
chuỗi con là một tập con của chuỗi khác. Trong trường hợp startIndex là inclusive (là bao
gồm cả chỉ mục đầu tiên này) và endIndex là exclusive (là loại trừ đi chỉ mục đầu tiên
này).
Ghi chú: Chỉ mục bắt đầu tính từ 0.
Bạn có thể lấy chuỗi con từ đối tượng String đã cho bởi một trong hai phương thức sau:
public String substring(int startIndex): Phương thức này trả về đối tượng String mới chứa
chuỗi con của chuỗi đã cho từ chỉ mục startIndex đã xác định (đây là inclusive).
public String substring(int startIndex, int endIndex): Phương thức này trả về đối tượng
String mới chứa chuỗi con của chuỗi đã cho từ chỉ mục startIndex (đây là inclusive) tới
chỉ mục endIndex (đây là exclusive) đã xác định.
Bạn theo dõi ví dụ sau để hiểu startIndex và endIndex:
String s="hello";
System.out.println(s.substring(0,2));//he
Trong chuỗi con trên, 0 trỏ tới h nhưng 2 trỏ tới e (bởi vì chỉ mục kết thúc là exclusive).
Do đó, chương trình trên sẽ in ra từ "he".
Ví dụ về chuỗi con trong Java
Dưới đây là ví dụ đơn giản về chuỗi con trong Java:
public class Chuoicon{
public static void main(String args[]){
String s="Trang Vietjack";
System.out.println(s.substring(5));//Vietjack
System.out.println(s.substring(0,5));//Trang
}
}
5.6 Phương thức của lớp String trong Java
Lớp java.lang.String cung cấp rất nhiều phương thức để giúp bạn thao tác và xử lý các
chuỗi. Bởi sự giúp đỡ của các phương thức này, chúng ta có thể thực hiện các hoạt động
trên chuỗi như cắt chuỗi, nối chuỗi, chuyển đổi chuỗi, so sánh chuỗi, thay thế chuỗi,
Java String là một khái niệm mạnh mẽ bởi vì mọi thứ được đối xử như là một String nếu
bạn đệ trình bất cứ form nào trong các ứng dụng dựa trên window, dựa trên web, mobile.
Phần dưới đây chúng tôi sẽ trình bày cho bạn một số phương thức quan trọng của lớp
String trong Java.
Phương thức toUpperCase() và toLowerCase() của lớp String trong Java
Phương thức toUpperCase() để chuyển đổi chuỗi thành chữ hoa và phương thức
toLowerCase() để chuyển đổi chuỗi thành chữ thường. Ví dụ:
String s="Vietjack";
System.out.println(s.toUpperCase());//Chuyen doi thanh VIETJACK
System.out.println(s.toLowerCase());//Chuyen doi thanh vietjack
System.out.println(s);//Vietjack(khong co thay doi nao)
Chương trình trên sẽ cho kết quả:
VIETJACK
vietjack
Vietjack
Phương thức trim() của lớp String trong Java
Phương thức trim() trong Java loại bỏ các khoảng trống trắng ở trước và sau chuỗi
(leading và trailing). Ví dụ:
String s=" Vietjack ";
System.out.println(s);//in ra chuoi nhu ban dau Vietjack (van con khoang trang
whitespace)
System.out.println(s.trim());//in ra chuoi sau khi da cat cac khoang trong trang Vietjack
Phương thức startWith() và endsWith() của lớp String trong Java
String s="Vietjack";
System.out.println(s.startsWith("Vi"));//true
System.out.println(s.endsWith("k"));//true
Phương thức charAt() của lớp String trong Java
Phương thức charAt() trả về ký tự tại chỉ mục đã cho. Ví dụ:
String s="Vietjack";
System.out.println(s.charAt(0));//tra ve V
System.out.println(s.charAt(3));//tra ve t
Phương thức length() của lớp String trong Java
Phương thức length() trả về độ dài của chuỗi. Ví dụ:
String s="Vietjack";
System.out.println(s.length());//tra ve do dai la 7
Phương thức intern của lớp String trong Java
Ban đầu, một Pool của các chuỗi là trống, được duy trì riêng cho lớp String. Khi phương
thức intern được gọi, nếu Pool đã chứa một chuỗi bằng với đối tượng String như khi được
xác định bởi phương thức equals(object), thì chuỗi từ Pool được trả về. Nếu không thì,
đối tượng String này được thêm vào Pool và một tham chiếu tới đối tượng String này
được trả về. Ví dụ:
String s=new String("Vietjack");
String s2=s.intern();
System.out.println(s2);//tra ve Vietjack
Phương thức valueOf() của lớp String trong Java
Phương thức valueOf() trả về biểu diễn chuỗi của giá trị đã cho. Phương thức này biến
đổi kiểu đã cho như int, long, float, double, Boolean, char, và mảng char thành chuỗi. Ví
dụ:
int a=10;
String s=String.valueOf(a);
System.out.println(s+10); //In ra ket qua la 1010
Phương thức replace() của lớp String trong Java
Phương thức replace() thay thế tất cả sự xuất hiện của dãy ký tự đầu bởi dãy ký tự thứ
hai. Ví dụ:
String s1="Java la mot ngon ngu lap trinh. Java la mot nen tang. Java la mot hon dao.";
String replaceString=s1.replace("Java","HaLong");//thay the tat ca su xuat hien cua
"Java" thanh "HaLong"
System.out.println(replaceString);
Chương trình trên sẽ cho kết quả dạng:
HaLong la mot ngon ngu lap trinh. HaLong la mot nen tang. HaLong la mot hon dao.
5.7 Lớp StringBuffer trong Java
Lớp StringBuffer trong Java được sử dụng để tạo chuỗi có thể sửa đổi (chuỗi
dạng mutable). Lớp StringBuffer là giống như lớp String trong Java, ngoại trừ ở điểm là
nó là có thể sửa đổi.
Ghi chú: Lớp StringBuffer là an toàn luồng (Thread-safe), ví dụ: nhiều Thread không thể
truy cập nó đồng thời. Vì thế nó là an toàn và sẽ cho kết quả trong một thứ tự.
Các Constructor quan trọng của lớp StringBuffer trong Java
StringBuffer(): tạo một bộ đệm chuỗi trống với dung lượng capacity ban đầu là 16.
StringBuffer(String str): tạo một bộ đệm chuỗi với chuỗi đã xác định.
StringBuffer(int capacity): tạo một bộ đệm chuỗi trống với dung lượng capacity đã cho.
Các phương thức quan trọng của lớp StringBuffer trong Java
1. public synchronized StringBuffer append(String s): được sử dụng để phụ thêm
(append) chuỗi đã cho với chuỗi này. Phương thức append() được nạp chồng giống dạng
append(char), append(boolean), append(int), append(float), append(double) ...
2. public synchronized StringBuffer insert(int offset, String s): được sử dụng để chèn
chuỗi đã cho với chuỗi này tại vị trí đã cho. Phương thức insert() được nạp chồng giống
dạng insert(int, char), insert(int, boolean), insert(int, int), insert(int, float), insert(int,
double) ...
3. public synchronized StringBuffer replace(int startIndex, int endIndex, String str): được
sử dụng để thay thế chuỗi từ chỉ mục ban đầu startIndex và chỉ mục kết thúc endIndex đã
cho.
4. public synchronized StringBuffer delete(int startIndex, int endIndex): được sử dụng để
xóa chuỗi từ chỉ mục startIndex và endIndex đã cho.
5. public synchronized StringBuffer reverse(): được sử dụng để đảo ngược chuỗi.
6. public int capacity(): được sử dụng để trả về dung lượng capacity hiện tại.
7. public void ensureCapacity(int minimumCapacity): được sử dụng để bảo đảm rằng
capacity ít nhất bằng với minimum đã cho.
8. public char charAt(int index): được sử dụng để trả về ký tự tại vị trí đã cho.
9. public int length(): được sử dụng để trả về độ dài của chuỗi (chẳng hạn như tổng số ký
tự).
10. public String substring(int beginIndex): được sử dụng để trả về chuỗi con từ chỉ mục
bắt đầu beginIndex đã cho.
11. public String substring(int beginIndex, int endIndex): được sử dụng để trả về chuỗi
con từ beginIndex đến endIndex đã cho.
Chuỗi dạng mutable là gì?
Một chuỗi mà có thể sửa đổi được xem như là chuỗi dạng mutable. Các
lớp StringBuffer và StringBuilder được sử dụng để tạo các chuỗi dạng mutable.
Phương thức append() của lớp StringBuffer trong Java
Phương thức append() được sử dụng để nối chuỗi tham số đã cho với chuỗi này. Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuffer sb=new StringBuffer("Hello ");
sb.append("Java");//bay gio chuoi ban dau bi thay doi
System.out.println(sb);//in ra ket qua la Hello Java
}
}
Phương thức insert() của lớp StringBuffer trong Java
Phương thức insert() chèn chuỗi đã cho vào chuỗi này tại vị trí đã cho. Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuffer sb=new StringBuffer("Hello ");
sb.insert(1,"Java");//bay gio chuoi ban dau bi thay doi
System.out.println(sb);//in ra ket qua la HJavaello
}
}
Phương thức replace() của lớp StringBuffer trong Java
Phương thức replace() thay thế chuỗi đã cho bắt đầu từ chỉ mục beginIndex tới endIndex.
Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuffer sb=new StringBuffer("Hello");
sb.replace(1,3,"Java");
System.out.println(sb);//in ra ket qua la HJavalo
}
}
Phương thức delete() của lớp StringBuffer trong Java
Phương thức delete() xóa chuỗi bắt đầu từ chỉ mục beginIndex tới endIndex đã cho. Ví
dụ:
class VIETJACK{
public static void main(String args[]){
StringBuffer sb=new StringBuffer("Hello");
sb.delete(1,3);
System.out.println(sb);//in ra ket qua la Hlo
}
}
Phương thức reverse() của lớp StringBuffer trong Java
Phương thức reverse() đảo ngược chuỗi hiện tại. Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuffer sb=new StringBuffer("Hello");
sb.reverse();
System.out.println(sb);//in ra ket qua la olleH
}
}
Phương thức capacity() của lớp StringBuffer trong Java
Phương thức capacity() trả về dung lượng capacity hiện tại của bộ đệm. Dung lượng
capacity mặc định của bộ đệm là 16. Nếu số ký tự tăng lên từ dung lượng hiện tại, nó
tăng dung lượng theo công thức (oldcapacity*2)+2. Ví dụ, nếu dung lượng hiện tại là 16,
nó sẽ là (16*2)+2=34. Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuffer sb=new StringBuffer();
System.out.println(sb.capacity());//mac dinh la 16
sb.append("Hello");
System.out.println(sb.capacity());//bay gio la 16
sb.append("Java la mot ngon ngu lap trinh manh me");
System.out.println(sb.capacity());//bay gio la (16*2)+2=34 vi du cua cong thuc
(oldcapacity*2)+2
}
}
Phương thức ensureCapacity() của lớp StringBuffer trong Java
Phương thức ensureCapcity() bảo đảm rằng capacity ít nhất bằng với minimum đã cho.
Nếu nó lớn hơn capacity hiện tại, nó tăng capacity theo công thức (oldcapacity*2)+2. Ví
dụ, nếu dung lượng hiện tại là 16, nó sẽ là (16*2)+2=34. Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuffer sb=new StringBuffer();
System.out.println(sb.capacity());//mac dinh la 16
sb.append("Hello");
System.out.println(sb.capacity());//bay gio la 16
sb.append("Java la mot ngon ngu lap trinh manh me");
System.out.println(sb.capacity());//bay gio la (16*2)+2=34 vi du cua cong thuc
(oldcapacity*2)+2
sb.ensureCapacity(10);//bay gio khong phai thay doi
System.out.println(sb.capacity());//bay gio la 34
sb.ensureCapacity(50);//bay gio la (34*2)+2
System.out.println(sb.capacity());//bay gio la 70
}
}
5.8 StringBuilder trong Java
Lớp StringBuilder trong Java được sử dụng để tạo chuỗi có thể thay đổi (chuỗi
dạng mutable). Lớp StringBuilder là giống như lớp StringBuffer ngoại trừ rằng nó là
không đồng bộ. Lớp này có sẵn từ JDK 1.5.
Các Constructor quan trọng của lớp StringBuilder trong Java
StringBuilder(): tạo một Builder trống với dung lượng capacity ban đầu là 16.
StringBuilder(String str): tạo một Builder với chuỗi đã xác định.
StringBuilder(int capacity): tạo một Builder trống với dung lượng capacity đã cho.
Các phương thức quan trọng của lớp StringBuffer trong Java
Bảng dưới đây liệt kê và miêu tả chi tiết một số phương thức quan trọng của lớp
StringBuffer trong Java:
Phương thức Miêu tả
public StringBuilder append(String s) Được sử dụng để phụ thêm (append) chuỗi
đã cho với chuỗi này. Phương thức append()
được nạp chồng giống dạng append(char),
append(boolean), append(int),
append(float), append(double) ...
public StringBuilder insert(int offset, String
s)
Được sử dụng để chèn chuỗi đã cho với
chuỗi này tại vị trí đã cho. Phương thức
insert() được nạp chồng giống dạng
insert(int, char), insert(int, boolean),
insert(int, int), insert(int, float), insert(int,
double) ...
public StringBuilder replace(int startIndex,
int endIndex, String str)
Được sử dụng để thay thế chuỗi từ chỉ mục
ban đầu startIndex và chỉ mục kết thúc
endIndex đã cho
public StringBuilder delete(int startIndex,
int endIndex)
Được sử dụng để xóa chuỗi từ chỉ mục
startIndex và endIndex đã cho
public StringBuilder reverse() Được sử dụng để đảo ngược chuỗi
public int capacity() Được sử dụng để trả về dung lượng capacity
hiện tại
public void ensureCapacity(int
minimumCapacity)
Được sử dụng để bảo đảm rằng capacity ít
nhất bằng với minimum đã cho
public char charAt(int index) Được sử dụng để trả về ký tự tại vị trí đã
cho
public int length() Được sử dụng để trả về độ dài của chuỗi
(chẳng hạn như tổng số ký tự)
public String substring(int beginIndex) Được sử dụng để trả về chuỗi con từ chỉ
mục bắt đầu beginIndex đã cho
public String substring(int beginIndex, int
endIndex)
Được sử dụng để trả về chuỗi con từ
beginIndex đến endIndex đã cho
Phương thức append() của lớp StringBuffer trong Java
Phương thức append() được sử dụng để nối chuỗi tham số đã cho với chuỗi này. Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuilder sb=new StringBuilder("Hello ");
sb.append("Java");//bay gio chuoi ban dau bi thay doi
System.out.println(sb);//in ra ket qua la Hello Java
}
}
Phương thức insert() của lớp StringBuffer trong Java
Phương thức insert() chèn chuỗi đã cho vào chuỗi này tại vị trí đã cho. Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuilder sb=new StringBuilder("Hello ");
sb.insert(1,"Java");//bay gio chuoi ban dau bi thay doi
System.out.println(sb);//in ra ket qua la HJavaello
}
}
Phương thức replace() của lớp StringBuffer trong Java
Phương thức replace() thay thế chuỗi đã cho bắt đầu từ chỉ mục beginIndex tới endIndex.
Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuilder sb=new StringBuilder("Hello");
sb.replace(1,3,"Java");
System.out.println(sb);//in ra ket qua la HJavalo
}
}
Phương thức delete() của lớp StringBuffer trong Java
Phương thức delete() xóa chuỗi bắt đầu từ chỉ mục beginIndex tới endIndex đã cho. Ví
dụ:
class VIETJACK{
public static void main(String args[]){
StringBuilder sb=new StringBuilder("Hello");
sb.delete(1,3);
System.out.println(sb);//in ra ket qua la Hlo
}
}
Phương thức reverse() của lớp StringBuffer trong Java
Phương thức reverse() đảo ngược chuỗi hiện tại. Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuilder sb=new StringBuilder("Hello");
sb.reverse();
System.out.println(sb);//in ra ket qua la olleH
}
}
Phương thức capacity() của lớp StringBuffer trong Java
Phương thức capacity() trả về dung lượng capacity hiện tại của bộ đệm. Dung lượng
capacity mặc định của bộ đệm là 16. Nếu số ký tự tăng lên từ dung lượng hiện tại, nó
tăng dung lượng theo công thức (oldcapacity*2)+2. Ví dụ, nếu dung lượng hiện tại là 16,
nó sẽ là (16*2)+2=34. Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuilder sb=new StringBuilder();
System.out.println(sb.capacity());//mac dinh la 16
sb.append("Hello");
System.out.println(sb.capacity());//bay gio la 16
sb.append("Java la mot ngon ngu lap trinh manh me");
System.out.println(sb.capacity());//bay gio la (16*2)+2=34 vi du cua cong thuc
(oldcapacity*2)+2
}
}
Phương thức ensureCapacity() của lớp StringBuffer trong Java
Phương thức ensureCapcity() bảo đảm rằng capacity ít nhất bằng với minimum đã cho.
Nếu nó lớn hơn capacity hiện tại, nó tăng capacity theo công thức (oldcapacity*2)+2. Ví
dụ, nếu dung lượng hiện tại là 16, nó sẽ là (16*2)+2=34. Ví dụ:
class VIETJACK{
public static void main(String args[]){
StringBuilder sb=new StringBuilder();
System.out.println(sb.capacity());//mac dinh la 16
sb.append("Hello");
System.out.println(sb.capacity());//bay gio la 16
sb.append("Java la mot ngon ngu lap trinh manh me");
System.out.println(sb.capacity());//bay gio la (16*2)+2=34 vi du cua cong thuc
(oldcapacity*2)+2
sb.ensureCapacity(10);//bay gio khong phai thay doi
System.out.println(sb.capacity());//bay gio la 34
sb.ensureCapacity(50);//now (34*2)+2
System.out.println(sb.capacity());//bay gio la 70
}
}
5.9 So sánh lớp String và StringBuffer trong Java
Có nhiều điểm khác nhau giữa lớp String và StringBuffer trong Java. Bảng dưới liệt kê
các điểm khác nhau này:
Lớp String Lớp
StringBuffer
Lớp String là không thể thay đổi (immutable) Lớp
StringBuffer
là có thể
thay đổi
(mutable)
Lớp String là chậm và tiêu thụ nhiều bộ nhớ hơn khi bạn nối
nhiều chuỗi bởi vì mỗi khi nối chuỗi, nó tạo instance mới
StringBuffer
là nhanh và
tiêu thụ ít
bộ nhớ hơn
khi bạn nối
các chuỗi
Lớp String ghi đè phương thức equals() của lớp Object. Vì
thế bạn có thể so sánh các nội dung của hai chuỗi bởi phương
thức equals()
Lớp
StringBuffer
không ghi
đè phương
thức
equals() của
lớp Object
Kiểm tra hiệu suất của lớp String và StringBuffer trong Java
public class Test1{
public static String concatWithString() {
String t = "Java";
for (int i=0; i<10000; i++){
t = t + "Vietjack";
}
return t;
}
public static String concatWithStringBuffer(){
StringBuffer sb = new StringBuffer("Java");
for (int i=0; i<10000; i++){
sb.append("Vietjack");
}
return sb.toString();
}
public static void main(String[] args){
long startTime = System.currentTimeMillis();
concatWithString();
System.out.println("Thoi gian tieu ton boi noi chuoi voi String:
"+(System.currentTimeMillis()-startTime)+"ms");
startTime = System.currentTimeMillis();
concatWithStringBuffer();
System.out.println("Thoi gian tieu ton boi noi chuoi voi StringBuffer:
"+(System.currentTimeMillis()-startTime)+"ms");
}
}
Chương trình trên sẽ cho kết quả dạng:
Thoi gian tieu ton boi noi chuoi voi String: 578ms
Thoi gian tieu ton boi noi chuoi voi StringBuffer: 0ms
Kiểm tra HashCode của lớp String và StringBuffer trong Java
Như bạn có thể thấy trong chương trình dưới đây, lớp String trả về giá trị Hashcode mới
khi bạn nối chuỗi nhưng StringBuffer trả về cùng giá trị Hashcode.
public class Test2{
public static void main(String args[]){
System.out.println("Kiem tra Hashcode cua String:");
String str="java";
System.out.println(str.hashCode());
str=str+"tpoint";
System.out.println(str.hashCode());
System.out.println("Kiem tra Hashcode cua StringBuffer:");
StringBuffer sb=new StringBuffer("java");
System.out.println(sb.hashCode());
sb.append("tpoint");
System.out.println(sb.hashCode());
}
}
Chương trình trên sẽ cho kết quả dạng:
Kiem tra Hashcode cua String:
3254818
229541438
Kiem tra Hashcode cua StringBuffer:
118352462
118352462
5.10 So sánh lớp StringBuffer và StringBuilder trong Java
Có nhiều điểm khác nhau giữa lớp String và StringBuffer trong Java. Bảng dưới liệt kê
các điểm khác nhau này:
Lớp StringBuffer Lớp StringBuilder
Lớp StringBuffer là đồng bộ (synchronized), tức
là an toàn luồng (thread safe). Nghĩa là hai
Thread không thể gọi đồng thời các phương thức
của lớp StringBuffer
StringBuilder là không đồng
bộ (non-synchronized) tức là
không an toàn luồng. Nghĩa là
hai Thread có thể gọi đồng thời
các phương thức của lớp
StringBuilder
StringBuffer là kém hiệu quả hơn StringBuilder StringBuilder là hiệu quả
hơn StringBuffer
Ví dụ về lớp StringBuffer trong Java
public class BufferTest{
public static void main(String[] args){
StringBuffer buffer=new StringBuffer("hello");
buffer.append("java");
System.out.println(buffer);
}
}
Chương trình trên sẽ cho kết quả dạng:
hellojava
Ví dụ về lớp StringBuilder trong Java
public class BuilderTest{
public static void main(String[] args){
StringBuilder builder=new StringBuilder("hello");
builder.append("java");
System.out.println(builder);
}
}
Chương trình trên sẽ cho kết quả dạng:
hellojava
Kiểm tra hiệu suất của lớp StringBuffer và StringBuilder trong Java
Bạn thử ví dụ đơn giản sau để kiểm tra hiệu suất của lớp StringBuffer và lớp
StringBuilder trong Java:
public class ConcatTest{
public static void main(String[] args){
long startTime = System.currentTimeMillis();
StringBuffer sb = new StringBuffer("Java");
for (int i=0; i<10000; i++){
sb.append("Vietjack");
}
System.out.println("Thoi gian tieu ton boi StringBuffer: " +
(System.currentTimeMillis() - startTime) + "ms");
startTime = System.currentTimeMillis();
StringBuilder sb2 = new StringBuilder("Java");
for (int i=0; i<10000; i++){
sb2.append("Vietjack");
}
System.out.println("Thoi gian tieu ton boi StringBuilder: " +
(System.currentTimeMillis() - startTime) + "ms");
}
}
Chương trình trên sẽ cho kết quả dạng:
Time taken by StringBuffer: 16ms
Time taken by StringBuilder: 0ms
Bài 7. Bài tập và thảo luận về Case study
ATM (1)
7.1. Các yêu cầu của ATM
OOP có 4 tính chất đặc thù chính, các ngôn ngữ OOP nói chung đều có cách để diễn tả:
Tính đóng gói: Có thể gói dữ liệu (data, ~ biến, trạng thái) và mã chương trình (code,
~ phương thức) thành một cục gọi là lớp (class) để dễ quản lí. Trong cục này thường
data rất rối rắm, không tiện cho người không có trách nhiệm truy cập trực tiếp, nên
thường ta sẽ che dấu data đi, chỉ để lòi phương thức ra ngoài. Ví dụ hàng xóm sang
mượn búa, thay vì bảo hàng xóm cứ tự nhiên vào lục lọi, ta sẽ bảo: "Ấy bác ngồi chơi
để tôi bảo cháu lấy cho". Ngôn ngữ Ruby "phát xít" đến nỗi dấu tiệt data, cấm không
cho truy cập từ bên ngoài. Ngoài ra, các lớp liên quan đến nhau có thể được gom
chung lại thành package (tùy ngôn ngữ mà còn gọi là module, namespace v.v.).
Tính trừu tượng: Có câu "program to interfaces, not to concrete implementations".
Nghĩa là khi viết chương trình theo phong cách hướng đối tượng, khi thiết kế các đối
tượng, ta cần rút tỉa ra những đặc trưng của chúng, rồi trừu tượng hóa thành các
interface, và thiết kế xem chúng sẽ tương tác với nhau như thế nào. Nói cách khác,
chúng ta định ra các interface và các contract mà chúng cần thỏa mãn.
Tính thừa kế: Lớp cha có thể chia sẻ dữ liệu và phương thức cho các lớp con, các lớp
con khỏi phải định nghĩa lại những logic chung, giúp chương trình ngắn gọn. Nếu lớp
cha là interface, thì lớp con sẽ di truyền những contract trừu tượng từ lớp cha.
Tính đa hình: Đối tượng có thể thay đổi kiểu (biến hình). (1) Với các ngôn ngữ OOP
có kiểu, có thể mượn phát biểu của C++ "con trỏ kiểu lớp cha có thể dùng để trỏ đến
đối tượng kiểu lớp con". Như vậy khi khai báo chỉ cần khai báo p có kiểu lớp cha, còn
sau đó nó trỏ đến đâu thì kệ cha con nó: nếu cha và con cùng có phương thức m, thì từ
p cứ lôi m ra gọi thì chắc chắn gọi được, không cần biết hiện tại p đang trỏ đến cha
hay con. Khi lớp B thừa kế từ lớp A, thì đối tượng của lớp B có thể coi là đối tượng
của lớp A, vì B chứa nhiều thứ thừa kế từ A. (2) Với ngôn ngữ OOP không có kiểu
như Ruby, có thể mượn phát biểu của phương pháp xác định kiểu kiểu con vịt: "nếu p
đi như vịt nói như vịt, thì cứ coi nó là vịt". Như vậy nếu lớp C có phương thức m, mà
có thể gọi phương thức m từ đối tượng p bất kì nào đó, thì cứ coi p có kiểu là C.
Để dễ nhớ, có thể chia 4 đặc thù làm 2 nhóm:
1. Nhóm 1: tính chất 1. Tính đóng gói là tính dễ nhận thấy nhất nếu bạn bắt đầu học
OOP sau khi đã học qua những ngôn ngữ thủ tục như C và Pascal (thường trường
phổ thông ở Việt Nam đều dạy).
2. Nhóm 2: tính chất 2, 3, và 4 đi một dây với nhau.
7.2. Cách xây dựng lớp và đối tượng
1. Các thành phần trong bản vẽ Class
Trước tiên, chúng ta xem một bản vẽ Class.
Hình 1. Ví dụ về Class Diagram của ATM
Ví dụ trên là Class Diagram của ứng dụng ATM. Tiếp theo chúng ta sẽ bàn kỹ về các
thành phần của bản vẽ này và lấy ứng dụng về ATM ở trên để minh họa.
Classes (Các lớp)
Class là thành phần chính của bản vẽ Class Diagram. Class mô tả về một nhóm đối tượng
có cùng tính chất, hành động trong hệ thống. Ví dụ mô tả về khách hàng chúng ta dùng
lớp “Customer”. Class được mô tả gồm tên Class, thuộc tính và phương thức.
Hình 2. Ký hiệu về Class
Trong đó,
– Class Name: là tên của lớp.
– Attributes (thuộc tính): mô tả tính chất của các đối tượng. Ví dụ như khách hàng
có Mã khách hàng, Tên khách hàng, Địa chỉ, Ngày sinh v.v
– Method (Phương thức): chỉ các hành động mà đối tượng này có thể thực hiện
trong hệ thống. Nó thể hiện hành vi của các đối tượng do lớp này tạo ra.
Hình 3. Ví dụ về một Class
Một số loại Class đặc biệt như Abstract Class (lớp không tạo ra đối tượng), Interface (lớp
khai báo mà không cài đặt) v.v.. chúng ta xem thêm các tài liệu về lập trình hướng đối
tượng để hiểu rõ hơn các vấn đề này.
2. Relationship (Quan hệ)
Relationship thể hiện mối quan hệ giữa các Class với nhau. Trong UML 2.0 có các quan
hệ thường sử dụng như sau:
– Association
– Aggregation
– Composition
– Generalization
Chúng ta sẽ lần lượt tìm hiểu về chúng.
+ Association
Association là quan hệ giữa hai lớp với nhau, thể hiện chúng có liên quan với nhau.
Association thể hiện qua các quan hệ như “has: có”, “Own: sở hữu” v.v
Hình 4. Ví dụ về Association
Ví dụ quan hệ trên thể hiện Khách hàng nắm giữ Tài khoản và Tài khoản được sở hữu
bởi Khách hàng.
+ Aggregation
Aggregation là một loại của quan hệ Association nhưng mạnh hơn. Nó có thể cùng thời
gian sống (cùng sinh ra hoặc cùng chết đi)
Hình 5. Ví dụ về Aggregation
Ví dụ quan hệ trên thể hiện lớp Window(cửa sổ) được lắp trên Khung cửa hình chữ nhật.
Nó có thể cùng sinh ra cùng lúc.
+ Composition
Composition là một loại mạnh hơn của Aggregation thể hiện quan hệ class này là một
phần của class kia nên dẫn
Các file đính kèm theo tài liệu này:
- 01200016_6026_1983557.pdf