TL; ดร
แคช Java บรรจุกล่องกรณีจำนวนเต็มจากไป-128
127
เนื่องจากคุณกำลังใช้==
เพื่อเปรียบเทียบการอ้างอิงอ็อบเจ็กต์แทนค่าเฉพาะอ็อบเจ็กต์ที่แคชเท่านั้นที่จะจับคู่ ทำงานกับlong
ค่าดั้งเดิมที่ไม่มีกล่องหรือใช้.equals()
เพื่อเปรียบเทียบLong
วัตถุของคุณ
เวอร์ชันยาว (เล่นสำนวนเจตนา)
เหตุใดจึงมีปัญหาในการเปรียบเทียบตัวแปร Long ที่มีค่ามากกว่า 127 หากชนิดข้อมูลของตัวแปรด้านบนเป็นแบบดั้งเดิม (แบบยาว) โค้ดจะใช้ได้กับทุกค่า
Java แคชจำนวนเต็มวัตถุกรณีจากช่วง -128 ถึง 127 ที่กล่าวว่า:
- หากคุณตั้งค่าให้ตัวแปร N Long เป็นค่า
127
( แคช ) อินสแตนซ์อ็อบเจ็กต์เดียวกันจะถูกชี้โดยการอ้างอิงทั้งหมด (N ตัวแปร 1 อินสแตนซ์)
- หากคุณตั้งค่าให้ตัวแปร N Long เป็นค่า
128
( ไม่ได้แคช ) คุณจะมีอินสแตนซ์วัตถุที่อ้างอิงทุกรายการ (ตัวแปร N, N อินสแตนซ์)
นั่นคือเหตุผลนี้:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2);
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4);
ผลลัพธ์นี้:
จริง
เท็จ
สำหรับ127Lคุ้มค่าเนื่องจากการอ้างอิงทั้งสอง (VAL1 และ VAL2) ชี้ไปที่วัตถุเช่นเดียวกันในหน่วยความจำ (แคช) true
ก็จะส่งกลับ
ในทางกลับกันสำหรับค่า128เนื่องจากไม่มีอินสแตนซ์สำหรับแคชในหน่วยความจำจึงมีการสร้างอินสแตนซ์ใหม่สำหรับการกำหนดค่าใหม่ใด ๆ สำหรับค่าแบบบรรจุกล่องส่งผลให้มีอินสแตนซ์สองรายการที่แตกต่างกัน (ชี้โดย val3 และ val4) และส่งกลับfalse
บน เปรียบเทียบระหว่างพวกเขา
สิ่งนี้เกิดขึ้นเพียงเพราะคุณกำลังเปรียบเทียบLong
การอ้างอิงออบเจ็กต์สองรายการไม่ใช่long
ค่าดั้งเดิมกับตัว==
ดำเนินการ หากไม่ใช่สำหรับกลไก Cache นี้การเปรียบเทียบเหล่านี้จะล้มเหลวเสมอดังนั้นปัญหาที่แท้จริงที่นี่คือการเปรียบเทียบค่าแบบบรรจุกล่องกับ==
ตัวดำเนินการ
การเปลี่ยนตัวแปรเหล่านี้เป็นlong
ชนิดดั้งเดิมจะป้องกันไม่ให้สิ่งนี้เกิดขึ้น แต่ในกรณีที่คุณต้องการให้โค้ดของคุณใช้อLong
อบเจ็กต์คุณสามารถทำการเปรียบเทียบเหล่านี้ได้อย่างปลอดภัยด้วยวิธีการต่อไปนี้:
System.out.println(val3.equals(val4)); // true
System.out.println(val3.longValue() == val4.longValue()); // true
System.out.println((long)val3 == (long)val4); // true
(จำเป็นต้องมีการตรวจสอบค่าว่างที่เหมาะสมแม้กระทั่งการหล่อ)
IMOเป็นความคิดที่ดีเสมอที่จะยึดติดกับ . equals ()วิธีการเมื่อจัดการกับการเปรียบเทียบวัตถุ
ลิงค์อ้างอิง:
.longValue()
หรือเปรียบเทียบค่าตอบแทนของ