Chào các bạn đã đến với chủ đề tiếp theo của mình. Hôm nay, mình sẽ tiếp tục tìm hiểu về Lớp Wrapper trong Java. Ở bài này, mình sẽ đi qua những nội dung như sau:
Nội dung
1. Lớp Wrapper là gì?
Trong những bài trước, chúng ta đã học qua các kiểu dữ liệu nguyên thủy trong java như int, long, float, etc. Các kiểu dữ liệu nguyên thuỷ này không có tác dụng gì ngoài lưu trữ các giá trị, nếu chúng ta muốn chuyển một số int sang String, hoặc là khởi tạo một số nguyên bởi một chuỗi số thì điều này là không thể.
Trong java có 8 kiểu dữ liệu nguyên thủy, nên cũng sẽ có 8 lớp Wrapper cho từng kiểu nguyên thủy này. Chúng bao gồm.
- Lớp Byte là lớp Wrapper cho kiểu dữ liệu byte.
- Lớp Short là lớp Wrapper cho kiểu dữ liệu short.
- Lớp Integer là lớp Wrapper cho kiểu dữ liệu int.
- Lớp Long là lớp Wrapper cho kiểu dữ liệu long.
- Lớp Float là lớp Wrapper cho kiểu dữ liệu float.
- Lớp Double là lớp Wrapper cho kiểu dữ liệu double.
- Lớp Character là lớp Wrapper cho kiểu dữ liệu char.
- Lớp Boolean là lớp Wrapper cho kiểu dữ liệu boolean.
2. Tại sao cần lớp Wrapper?
Trước tiên, các lớp Wrapper sẽ giúp chúng ta chuyển đổi qua lại giữa một kiểu dữ liệu nguyên thủy sang kiểu dữ liệu đối tượng và ngược lại.
Ví dụ:
int a = 20; // a là biến có kiểu dữ liệu int nguyên thủy
Integer i = Integer.valueOf(a); // i là biến có kiểu dữ liệu đối tượng Integer, được tạo ra từ biến nguyên thủy a
Bạn có thể thấy, biến a là kiểu int, còn biến i là kiểu Integer.
Ý tiếp theo cho câu hỏi tại sao này là, nếu với các kiểu dữ liệu nguyên thủy, bạn chỉ tạo ra biến rồi sử dụng giá trị của nó (nếu bạn không gán giá trị thì nó vẫn được tạo một giá trị mặc định). Còn với các kiểu đối tượng, giá trị mặc định của nó là null, giá trị null này để đánh dấu rằng biến chưa mang giá trị nào.
Ví dụ nếu chúng ta khai báo như sau:
int t = null;
System.out.println(t);
Thì chúng ta sẽ bị lỗi Error:(8, 17) java: incompatible types: <nulltype> cannot be converted to int
Mà phải wrapper class như sau:
Integer t = null;
System.out.println(t);
Bằng cách này chúng ta có thể kiểm tra biến này đã được gán giá trị hay chưa
if (t == null) {
// ...
}
Thêm nữa, một số cấu trúc khác bên trong ngôn ngữ Java, như các cấu trúc về các danh sách mà chúng ta sẽ làm quen sau như ArrayList hay Hashset đều chứa đựng các tập hợp kiểu dữ liệu đối tượng thay vì kiểu nguyên thủy, nên việc biết và vận dụng các lớp Wrapper là một bắt buộc.
Ví dụ chúng ta muốn có một ArrayList số nguyên và chúng ta khai báo như sau:
List<int> list = new ArrayList<>();
Chúng ta sẽ bị compile error. Và chúng ta sẽ phải sử dụng Wrapper class của int là Integer.
List<Integer> list = new ArrayList<>();
3. Chuyển đổi qua lại giữa kiểu nguyên thủy và kiểu wrapper
3.1. Chuyển Đổi Kiểu Nguyên Thủy Sang Kiểu Wrapper
Việc chuyển đổi một kiểu nguyên thủy sang kiểu Wrapper của nó người ta gọi là Boxing. Boxing ở đây mang ý nghĩa là đóng hộp, tức là đóng dữ liệu nguyên thủy vào trong cái hộp Wrapper của nó. Như ví dụ mà ở đầu topic, khi một kiểu int a được chuyển thành kiểu Integer i.
Bạn có thể thực hiện việc boxing thông qua các phương thức khởi tạo của các lớp Wrapper.
// Các dạng Boxing
int a = 500;
Integer i = new Integer(a);
Integer j = new Integer(500);
Float f = new Float(4.5);
Double d = new Double(5);
Character ch = new Character('a');
Boolean b = new Boolean(true);
Hoặc có thể gán trực tiếp các giá trị nguyên thủy vào cho các lớp Wrapper, cách này người ta còn gọi là Autoboxing, có nghĩa là hệ thống sẽ chuyển đổi một cách tự động.
int x = 25;
// autoboxing
Integer xObj = x;
System.out.println(xObj); // 25
3.2. Chuyển Đổi Kiểu Wrapper Sang Kiểu Nguyên Thủy
Ngược lại với trên kia, khi bạn chuyển từ một kiểu Wrapper sang kiểu nguyên thủy của nó người ta gọi là Unboxing, có nghĩa là mở hộp, tức là mở cái hộp Wrapper để lấy dữ liệu nguyên thủy ra.
// assign value to Integer object
Integer xObj = new Integer(25);
// unboxing
int x = xObj;
System.out.println(x); // 25
4. Autoboxing/Unboxing trong Java Collection
Autoboxing và unboxing được sử dụng khá phổ biến khi làm việc với Java collection. Hãy xem một ví dụ:
import java.util.ArrayList;
class Main {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
// insert value to the list
// autoboxing
list.add(5);
list.add(6);
System.out.println("ArrayList: " + list);
// access value from arraylist
// unboxing
int number = list.get(1);
System.out.println("Value at index 1: " + number);
}
}
Sau khi chạy đoạn code trên, kết quả được in như sau:
ArrayList: [5, 6]
Value at index 1: 6
Ở trên đã tạo một ArrayList
kiểu Integer
. Tuy nhiên, chúng ta truyền các giá trị int
vào Arraylist.
list.add(5);
list.add(6);
Trong trường hợp này, các giá trị nguyên thủy 5 và 6 được tự động chuyển đổi thành các giá trị kiểu Integer
(autoboxing).
Tương tự, khi truy cập các giá trị từ danh sách:
int number = list.get(1);
Giá trị kiểu Integer
6 được chuyển đổi thành kiểu nguyên thủy int
(unboxing)
5. Kết
Như vậy chúng ta đã tìm hiểu xong Lớp Wrapper trong Java. Cảm ơn các bạn đã theo dõi bài viết của mình. Chúc các bạn thành công. Hẹn gặp lại các bạn ở những chủ đề tiếp theo.