ไปเจอบทความนึงมาน่าสนใจดี ว่า ด้วยเรื่องของ ทำไม 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 ยากในการตรวจหา