ไปเจอบทความนึงมาน่าสนใจดี ว่า ด้วยเรื่องของ ทำไม 1 == 1 ถึงเป็น true แต่ 1000 == 1000 ถึงเป็น false ใน Java?

Integer a = 1000;
Integer b = 1000;
System.out.println(a == b); // false

Integer x = 1;
Integer y = 1;
System.out.println(x == y); // true

ประเด็นสำคัญ

การใช้งาน == กับ Wrapper Class (Integer) นั่น == ใช้วิธีการตรวจสอบแบบ reference equality (อ้างอิงหน่วยความจำ) ไม่ใช่ค่า

โดย Java นั้น จะมี Integer Cache (-128 ถึง 127) เพื่อ cache ค่า Integer ในช่วงนี้ไว้ เพื่อประสิทธิภาพ ซึ่งจำนวนในช่วงนี้ค่อนข้างให้บ่อย เช่น loop, index

ดังนั้น ค่าที่อยู่นอกช่วงนี้ (เช่น 1000) จะสร้าง object ใหม่ทุกครั้ง ทำให้การ reference ไม่ตรงกันนั่นเอง

เช่น

  • Integer x = 1; Integer y = 1; ใช้ object เดียวจาก cache → x == y เป็น true
  • Integer a = 1000; Integer b = 1000; → สร้างคนละ object → a == b เป็น false

วิธีที่ถูกต้องในการเปรียบเทียบค่า

ถ้าต้องการเปรียบเทียบค่าที่มากกว่า 999 ให้ใช้ .equals() แทน ==

เช่น a.equals(b)true แม้ค่าจะอยู่นอก cache

ทำไมเรื่องนี้สำคัญ

ถ้าหากเราใช้ == ใน test case เล็กๆ ตอนทดสอบมันจะผ่าน (เพราะอยู่ใน cache) แต่เมื่อขึ้นบน production แล้ว มันจะพัง เมื่อเจอค่าที่ใหญ่กว่า และเป็น bug ยากในการตรวจหา


Reference