นากกายสีมิ้นต์วางการ์ดวันที่สองใบที่เหมือนกันลงช่องเดียวบนโต๊ะมิ้นต์

JEP 401 Value Objects (Preview) ใน JDK 28: อ็อบเจ็กต์ไม่มี identity

น้องกายEngineering

ข้อมูล immutable อย่างวันที่หรือตัวเลขห่อ มักไม่ต้องการ identity ของอ็อบเจ็กต์ แต่ Java เดิมสร้างอ็อบเจ็กต์พร้อม identity เสมอ

JEP 401 สถานะ Integrated สำหรับ JDK 28 แนะนำ value objects แบบพรีวิว ปิดค่าเริ่มต้น ต้องเปิดด้วย --enable-preview

สิ่งที่เปลี่ยนในหัวผม

Value class ประกาศด้วยตัวปรับ value อินสแตนซ์ไม่มี identity

  • == เทียบค่าฟิลด์ ไม่ใช่ตำแหน่งหน่วยความจำ
  • ฟิลด์อินสแตนซ์เป็น final โดยนัย คลาสเป็น final โดยนัย (ยกเว้น abstract value class)
  • ซิงโครไนซ์บน value object ไม่ได้

ตัวอย่างจาก JEP: เมื่อพรีวิวเปิด Integer หลายตัวที่ห่อค่าเดียวกันอาจ == เป็นจริงแม้เคยอยู่นอกแคชเล็กๆ และ LocalDate สองตัวที่วันเดียวกันก็ == ได้

มี Objects.hasIdentity สำหรับถามว่าอ็อบเจ็กต์มี identity หรือไม่

ทำไมถึงเร็วขึ้นได้

เมื่อไม่มี identity JVM มีอิสระ flatten อ้างอิงลงในอาร์เรย์/ฟิลด์ หรือ scalarize บนสแต็ก ลดพอยน์เตอร์และภาระ GC โดยโปรแกรมยังเห็นเป็นอ็อบเจ็กต์อ้างอิงตามเดิม

ข้อควรระวังตอนย้าย

  • โค้ดที่พึ่ง == เพื่อแยกอินสแตนซ์ที่สร้างคนละครั้งอาจพัง
  • อย่าซิงโครไนซ์บนอินสแตนซ์ของคลาสที่ย้ายเป็น value
  • equals/hashCode ที่ไม่เคย override จะเปลี่ยนพฤติกรรมเมื่อเทียบกับ identity เดิม
  • การ serialize value class ที่ไม่ใช่ record ยังต้องช่วยด้วย writeReplace/readResolve ตามที่ JEP ระบุ

Recap

  • เปิดพรีวิวทั้งคอมไพล์และรันก่อนทดลอง value class
  • ใช้กับข้อมูล immutable ที่แทนกันได้
  • อย่าพึ่ง identity ของคลาสใน Platform API ที่กลายเป็น value เมื่อพรีวิวเปิด
  • อ่าน JEP 401 คู่กับ JEP 539 เรื่อง strict field init