Tóm Tắt
[Java] Hiểu về Primitive Type và Wrapper Objects
Trong thời gian rảnh rỗi những ngày cách lý tháng 4, mình có ý tưởng là ôn tập lại những kiến thức căn bản của lập trình. Mình nghĩ đây là thời gian tốt để mình có thể tổng hợp và ôn tập lại những kiến thức trong suốt quá trình làm developer. Và chủ đề hôm nay là Primitive type.
- Primitive type là gì? Wrapper Object là gì
- Khi nào sử dụng Primitive type, khi nào sử dụng Wrapper Object
Primitive Types
trong JAVA, chúng ta có 8 loại primitive data: boolean, byte, short, int, long, float, double, char. Ngoài ra các loại variable còn loại đều là Object reference type.
Primitive type còn được gọi là literal. Literal sử dụng để ám chỉ đây là vùng nhớ có dữ liệu định trước
Kích thước và dãy giá trị của Primitive type
+-----------+---------+-------------------------+
| Data Type | Size | Range |
+-----------+---------+-------------------------+
| byte | 1 byte | -128 to 127 |
| short | 2 bytes | -32,768 to 32,767 |
| int | 4 bytes | -2^31 to 2^31-1 |
| long | 8 bytes | -2^63 to 2^63-1 |
| float | 4 bytes | -3.4e38 to 3.4e38 |
| double | 8 bytes | -1.7e308 to 1.7e308 |
| boolean | 1 bit* | true or false |
| char | 2 bytes | '\u0000' to '\uffff' |
+-----------+---------+-------------------------+
Khai báo primitive type
Trong java, primitive type là dạng statically-typed. Điều này có nghĩ là phải khai báo trước thì mới được sử dụng.
byte b = '\u0045';
short s = 5;
int i = 10;
long l = 100L;
float f = 3.1415f;
double d = 500.25d;
boolean bool = false;
char c = 'A';
Khi tạo một biến primitive type không gán giá trị ban đầu. Tự động biến đó sẽ có giá trị mặc định.
Giá trị mặc định của primitive type
+-----------+---------------+
| Data Type | Default Value |
+-----------+---------------+
| byte | 0 |
| short | 0 |
| int | 0 |
| long | 0L |
| float | 0.0f |
| double | 0.0d |
| boolean | false |
| char | '\u0000' |
+-----------+---------------+
Wrapper Object
Bản chất là các Primitive type được đóng gói thành một object. Mỗi Primitive type đều có object tương ứng với nó
- byte, short, int, long, float, double, boolean, char
- Byte, Short, Integer, Long, Float, Double, Boolean, Character
Wrapper object có giá trị mặc định là null.
Wrapper object là một dạng immutable type. Điều này có nghĩ là giá trị sẽ không thay đổi trong lúc run-time. Vậy làm thế nào để thực hiện các phép toán với Wrapper Object?
Integer a = new Integer (3)
a + = 1
Compiler giải quyết bằng cách tạo ra một wrapper object có giá trị mới và gán ngược lại vào wrapper object bằng đầu. Nó được thực hiện tự động thông qua 2 cơ chế Autoboxing và Unboxing.
AutoBoxing
Đây là cơ thế tự động chuyển đổi Primitive type thành một wrapper object tương ứng.
List <Integer> numbers = new ArrayList <Integer>
for (int i = 0; i <10; i ++) {
numbers.add (i)
}
Mỗi lần i được thêm vào numbers, một Integer Object sẽ được tạo và thêm vào danh sách.
Unboxing
Ngược lại với Autoboxing, cơ chế này tự động chuyển đổi wrapper object thành primitive type tương ứng.
Integer a = new Integer(5)
int b = a
Hiệu suất Autoboxing và Unboxing
Autoboxing và unboxing sử dụng object trung gian để thực hiện việc chuyển đổi, do đó vô tình tạo ra nhiều object không cần thiết và tăng thêm công việc cho Garbage Collector.
Hãy cùng nhau phân tích ví dụ dưới đây
Integer number = new Integer(0)
for (int i = 0; i < 1000; i++){
number += i
}
Vấn đề nằm ở dòng number += i. Cơ chế thực hiện như sau:
- number += i được chuyển đổi thành number = number + i
- number được unboxing giá trị và cộng với i
- kế tiếp sẽ autoboxing (tạo mới Integer object) với giá trị có được.
- gán wrapper object tạo ở bước trên vào number
=> 1000 wrapper object sẽ được tạo ra gây nên sự lãng phí về tài nguyên bộ nhớ. Từ đó ảnh hướng đến hiệu suất của app.
Cách sử dụng
Theo cá nhân mình Wrapper Object được sử dụng trong các trường hợp sau:
- Khi sử dụng với Collections.
- Khi cần sử dụng giá trị null
- Khi cần lấy giá trị MIN, MAX của primitive type
Các trường hợp còn lại để nhanh chóng cho việc truy cập và tính toán, thì sử dụng primitive type là tối ưu nhất.
Tổng kết lại, Java hỗ trợ cho ta 8 loại primitive type, đồng thời cũng có 8 loại wrapper object tương ứng. Việc chuyển đổi qua lại giữa lại loại data này được thực hiện qua cơ chế Autoboxing và UnBoxing.
Hy vọng qua tổng hợp trên sẽ giúp các bạn đọc ôn tập lại những kiến thức đã được học.
Happy Coding!!!