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

เมื่อไหร่ควรใช้เมธอด intern() ของ String ใน Java

เมธอด intern() ของ String Class ใช้แก้ปัญหา String Duplication ประหยัดหน่วยความจำจาก Duplicate String Instances (เนื้อหาเหมือนกัน แต่อยู่คนละ Memory Location)

String Pool และ intern()

  • JVM มี String Pool (ใน Heap) เก็บ String Literal
  • String Literal เดียวกัน → ชี้ Object เดียวใน Pool
  • new String() สร้าง Object ใหม่เสมอ แม้ค่าเหมือน Literal ใน Pool
  • intern() บังคับให้ JVM คืน Reference จาก Pool (ถ้ามี) หรือเพิ่มเข้า Pool (ถ้ายังไม่มี)

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

  1. สร้าง String ด้วย new String() แล้วต้องการเปรียบเทียบด้วย == (Reference Equality)
  2. มี String จำนวนมากที่ซ้ำกัน (เช่น อ่านจากไฟล์/Database) ต้องการ deduplicate
  3. Memory-sensitive Application ที่ต้องการลด Heap Usage

ตัวอย่างโค้ด


public class StringInternClassTest {
    public static void main(String[] args) {
        String s1 = "Tutorix";              // Literal - ใน Pool
        String s2 = "Tutorix";              // Literal - เดียวกับ s1
        String s3 = new String("Tutorix");  // Heap Object ใหม่
        String s4 = s3.intern();            // บังคับดึงจาก Pool
        String s5 = "?Tutorix".substring(1); // Runtime String
        String s6 = s5.intern();            // intern() รันไทม์
        
        // == Comparison (Reference)
        System.out.println(s1 == s2);  // true  (Same Pool Ref)
        System.out.println(s2 == s3);  // false (Literal vs new Object)
        System.out.println(s3 == s4);  // false (new Object vs Pooled)
        System.out.println(s1 == s3);  // false
        System.out.println(s1 == s4);  // true  (Both from Pool)
        System.out.println(s1 == s5);  // false (Runtime String)
        System.out.println(s1 == s6);  // true  (Interned)
        
        // .equals() Comparison (Value)
        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
    }
}

ผลลัพธ์


true
false
false
false
true
false
true
true
true
true
true
true

ข้อควรระวัง

  • intern() มี Overhead (Hash lookup, Lock contention ใน Pool)
  • Java 7+ String Pool อยู่ใน Heap (PermGen → Metaspace → Heap)
  • ใช้ profiling ก่อนตัดสินใจ (ไม่ใช่ Silver Bullet)
  • ปกติใช้ .equals() เปรียบเทียบค่า ไม่ต้อง intern()