Phương thức intern() của String class dùng để giải quyết vấn đề trùng lặp chuỗi (string duplication) trong Java. Dùng intern() có thể tiết kiệm nhiều bộ nhớ bị tiêu tốn bởi các instance chuỗi trùng lặp. Chuỗi trùng lặp nếu có cùng nội dung nhưng chiếm vùng nhớ khác nhau.
JVM duy trì một vùng nhớ heap riêng (string pool) cho các string literal để tăng hiệu năng. Khi khai báo string literal, nó vào pool. Nếu biến khác gán cùng literal, nó lấy từ pool thay vì tạo object mới trong heap. Nhưng nếu chuỗi tạo bằng new constructor, object mới được tạo ngay cả khi literal đã có trong pool. Để buộc JVM lấy từ pool, dùng intern().
Java tự động intern tất cả string literal mặc định. intern() có thể dùng cho chuỗi tạo bằng new String() để so sánh bằng toán tử ==.
Ví dụ minh họa
public class StringInternClassTest {
public static void main(String[] args) {
String s1 = "Tutorix";
String s2 = "Tutorix";
String s3 = new String("Tutorix");
final String s4 = s3.intern();
String s5 = "?Tutorix".substring(1);
String s6 = s5.intern();
System.out.println(s1 == s2); // true - cùng literal trong pool
System.out.println(s2 == s3); // false - s3 là object mới
System.out.println(s3 == s4); // false - s3 heap, s4 pool
System.out.println(s1 == s3); // false
System.out.println(s1 == s4); // true - s4 từ pool
System.out.println(s1 == s5); // false - s5 object mới
System.out.println(s1 == s6); // true - s6 từ pool
System.out.println(s1.equals(s2)); // true
System.out.println(s2.equals(s3)); // true
System.out.println(s3.equals(s4)); // true
System.out.println(s1.equals(s4)); // true
System.out.println(s1.equals(s3)); // true
}
}
Kết quả đầu ra
true false false false true false true true true true true true
Khi nào nên dùng intern()
- Xử lý lượng lớn chuỗi lặp lại (XML parsing, log processing) để giảm bộ nhớ.
- Cần so sánh tham chiếu (==) thay vì equals() cho hiệu năng (hiếm khi cần).
- Tương tác với code cũ/lib yêu cầu string từ pool.
Cảnh báo
- Lạm dụng
intern()có thể làm String pool phình to, gây OutOfMemoryError: PermGen/Metaspace (Java 7- pool trong PermGen, Java 8+ trong heap). - Ưu tiên
equals()cho so sánh nội dung – an toàn, rõ ràng.