Cùng tìm hiểu String trong Java nào
Cùng tìm hiểu String trong Java nào
Trong
lập trình nói chung, String là một mảng gồm các kí tự. Khái niệm có vẻ đơn giản,
nhưng trong Java, người ta không chỉ dừng lại ở mức đơn giản như thế. Hôm nay mình
sẽ tập trung vào 2 mục tiêu:
1.
Các thành phần của String
2.
Tổ chức lưu trữ trong String
Phần 1: Các
thành phần của String
String
bản chất là một đối tượng được tạo thông qua lớp String. Vì Java có cung cấp mã
nguồn của các lớp nên chúng ta cùng nhau khai thác nó để hiểu rõ hơn nhé.
Vì
là đối tượng nên chúng ta sẽ xem thuộc tính của nó trước:
Như
chúng ta thấy, lớp String có 2 thuộc tính: value[] và hash (ở phiên bản cũ thì
có 4 thuộc tính: value[], offset, count và hash (xem chi tiết tại: http://www.docjar.com/html/api/java/lang/String.java.html)
).
Đầu
tiên ta thấy rõ value[] là một mảng gồm các char, vậy tức là String trong Java được
biểu diễn dưới hình thức của char array. Để đảm bảo hơn, ta thử soi hàm
length() của class String thực hiện thế nào:
Thế
thì chuẩn luôn rồi, phương thức length() sử dụng phương thức tính chiều dài của
mảng áp dụng trên value, tức mảng value chính là đại diện của String.
Cái
thứ 2 ít quan tâm hơn là hash. Thuộc tính hash lưu trữ dạng mã hóa của chuỗi, mặc
định của nó là 0, khi sử dụng hàm hashCode(), nó sẽ hash chuỗi và trả về như
sau
Thuộc
tính này chỉ thay đổi giá trị khi hashCode() thực thi. Mà phần này chúng ta chỉ
hiểu thôi, đừng quan tâm quá.
Về
offset và count, nó có nghĩa là vị trí đầu tiên và số lượng của String. Phần này
đã bị lược đi có lẽ do Java cảm thấy nó thừa. (Bạn nào quan tâm thì hãy so sánh
subString() giữa 2 class cũ và mới sẽ thấy sự khác biệt trước và sau khi lược bỏ).
Thôi
đi xa quá rồi. Chúng ta cùng tiếp tục giải quyết vấn đề thứ 2:
Phần 2: Tổ
chức lưu trữ trong String
Trong
Java, khi khởi tạo một đối tượng, giá trị này sẽ lưu vào trong mảng value.
Có
2 cách khởi tạo đối tượng:
Cách
1: Dùng toán tử new ( String s = new String(“Hello World”) )
Cách
2: Sử dụng dấu “=” ( String s = “Hello World” )
Điểm
giống nhau là cả 2 đều khởi tạo và lưu giá trị vào trong thuộc tính value. Tất
nhiên là sẽ có điểm khác nhau giữa 2 cách này, chúng ta cùng theo dõi tiếp.
Chúng
ta cùng làm quen với khái niệm String literal và String pool. Như các bạn đã biết,
khi khởi tạo 1 đối tượng bằng từ khóa new, giá trị sẽ được lưu trong bộ nhớ heap.
Nhưng đặc biệt, khi khởi tạo bằng “=”, phép khởi tạo này định nghĩa giá trị bên
phải dấu bằng là một literal và lưu vào trong một khu vực đặc biệt của heap gọi là
String pool. Điểm đặc biệt của nơi này là khi một đối tượng khởi tạo với giá trị
là String literal (tức dùng phép “=”), nó sẽ dò trong String pool xem có xâu nào
trùng với xâu mình cần dò không. Nếu trùng, đối tượng sẽ trỏ vào vị trí đó. Nếu
không, một giá trị mới sẽ lưu vào trong String pool.
Ví
dụ trên hình, ta có s1 khởi tạo với từ khóa new, nên sẽ lưu trong heap và bên
ngoài String pool. Tiếp đó, s2 khởi tạo bằng “=”, nó sẽ dò và lưu vào trong String
pool. Kế nữa, s3 cũng khởi tạo bằng “=”, lúc này s3 dò và tìm ra vị trí chứa “Hi”
trong String pool, s3 ngay lập tức trỏ tới vị trí này (tức s2 và s3 cùng trỏ tới
1 nơi chứa giá trị). s4 cũng tương tự như s1.
Giả
sử khi ta so sánh s1==s2, s2==s3, s4==s1 (ta hiểu là so địa chỉ mà biến trỏ tới),
ta thu được kết quả false, true, false. Nguyên nhân như đã giải thích ở trên.
Còn
một đặc điểm trong String gọi là immutable (bất biến). Bất biến ở đây
nghĩa là giá trị trong một ô nhớ không bị thay đổi. Giả sử ta có dòng code
Ta
có sơ đồ trước và sau khi substring như sau
Khi
thực hiện subString và “gán” vào s1 (thực ra là khởi tạo), lúc này s1 sẽ không
thay đổi giá trị mà thực hiện trỏ tới ô nhớ mới chứa kí tự đã subString. Ô nhớ
chứa “abc” vẫn không hề thay đổi, đó chính là tính bất biến của String.
Việc
sử dụng String pool trong Java giúp cho người lập trình tiết kiệm bộ nhớ rất
nhiều, chỉ cần trỏ vào cùng 1 vị trí là đã đỡ tốn thêm bộ nhớ để lưu trữ rồi.
Tổng
kết lại, ta nhớ các ý sau đây:
·
String là đối tượng
·
String được biểu diễn dưới dạng tập hợp mảng
char
·
String pool và String literal
·
String có tính bất biến
Nội dung bài viết thuộc về Lê Công Diễn.
Người viết: Lê
Công Diễn
Mang đi nhớ ghi nguồn
Nhận xét
Đăng nhận xét