Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Java

บทบาทของเมธอด String.intern() ใน Java

String ใน Java เป็น immutable class เก็บลำดับตัวอักษร อยู่ในแพ็กเกจ java.lang

String Constant Pool

String literal ทั้งหมด (เช่น "Hello") ถูกเก็บใน String Constant Pool (ส่วนหนึ่งของ Heap) JVM 保证相同內容的字面量只有一個副本


String a = "Hello";
String b = "Hello";
System.out.println(a == b); // true - same reference in pool

แต่ new String("Hello") สร้าง object ใหม่ใน Heap ทุกครั้ง (ไม่อยู่ใน pool)


String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b); // false - different objects
System.out.println(a.equals(b)); // true - same content

เมธอด intern()

public String intern() คืนค่า reference จาก String Pool:

  • ถ้า Pool มี string ที่ equals() แล้ว → คืน reference นั้น
  • ถ้าไม่มี → เพิ่ม string นี้เข้า Pool และคืน reference ใหม่

ผลลัพธ์: เรียก intern() บน string ที่มีเนื้อหาเดียวกัน จะได้ reference เดียวกัน (== คืน true)

ตัวอย่าง


public class InternExample {
    public static void main(String[] args) {
        String str1 = new String("Hello");
        str1 = str1.intern(); // เพิ่มใน pool / ดึงจาก pool
        
        String str2 = new String("Hello");
        str2 = str2.intern(); // ดึงจาก pool เดียวกัน
        
        System.out.println(str1 == str2); // true!
        System.out.println(str1.equals(str2)); // true
    }
}

ผลลัพธ์


true
true

เมื่อไหร่ควรใช้ intern()

  • Memory optimization: มี string ซ้ำกันเยอะ (เช่น อ่านจากไฟล์/DB, parsing XML/JSON) ใช้ intern() ลด memory
  • Performance: การเปรียบเทียบด้วย == เร็วกว่า equals() มาก (reference comparison)
  • Canonical representation: ต้องการให้ string เดียวกันมี instance เดียวกันเสมอ

ข้อควรระวัง

  • Java 6-: Pool อยู่ใน PermGen (ขนาดจำกัด, อาจ OutOfMemoryError) - ไม่แนะนำ intern() มากเกินไป
  • Java 7+: Pool ย้ายไป Heap (มี GC จัดการ) - ใช้ได้ปลอดภัยกว่า
  • String literal อยู่ใน pool แล้ว - "hello".intern() ไม่จำเป็น
  • Thread-safe แต่มี overhead (synchronized pool)

ตัวอย่างประยุกต์: Deduplication


public class StringDeduplication {
    private static final Map pool = new ConcurrentHashMap<>();
    
    public static String internCustom(String s) {
        return pool.computeIfAbsent(s, k -> k); // custom pool, ไม่ใช้ JVM pool
    }
}

สรุป

สถานการณ์ควรใช้ intern()?
String literalไม่จำเป็น (อยู่ใน pool แล้ว)
new String() จาก external input (เยอะ, ซ้ำ)ใช่ (Java 7+)
String ที่ไม่ซ้ำ/สร้างน้อยไม่จำเป็น (overhead ไม่คุ้ม)
ต้องการ == comparisonใช่ (หลัง intern)