Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Khi nào dùng phương thức intern() của String class trong Java

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.