"เนื่องจากนักพัฒนาสามารถสร้างชั้นเรียนที่อธิบายเกี่ยวกับตัวเลขได้ พวกเขาจึงตัดสินใจที่จะสร้างสรรค์เช่นเดียวกับนักพัฒนาจริงๆ"

"ขั้นแรก พวกเขาสร้างคลาส Number แบบนามธรรม ซึ่งมาจาก Byte, Short, Integer, Long, Float และ Double ซึ่งมีเมธอดที่ช่วยแปลงตัวเลขเป็นประเภทตัวเลขอื่นๆ"

เมธอดของคลาส Number
1
int intValue()
2
long longValue()
3
float floatValue()
4
double doubleValue()
5
byte byteValue()
6
short shortValue()

"ถูกต้อง ท้ายที่สุดคุณไม่สามารถเขียนสิ่งนี้:"

Long x = 100000;
Integer y = (Integer) x;

"ใช่ ประเภทเหล่านี้ไม่ใช่ประเภทดั้งเดิม นั่นเป็นเหตุผลที่เราใช้เมธอดของคลาส Number:"

Long x = 100000;
Integer y = x.intValue();

"แต่ยังมีอีกสองสามสิ่งที่ต้องพิจารณา เนื่องจากจำนวนเต็มไม่ใช่ int จึงไม่สามารถเปรียบเทียบวัตถุจำนวนเต็มกับตัวดำเนินการ «==» แบบคลาสสิกได้"

การเปรียบเทียบประเภทดั้งเดิม
int x = 500;
int y = 500;
x == y; //true
การเปรียบเทียบประเภทที่ไม่ใช่แบบดั้งเดิม
Integer x = 500;
Integer y = 500;
x == y; //false
x.equals(y); //true

"ถูกต้อง ยังไงก็ตาม ฉันไม่ได้คิดถึงเรื่องนั้นในทันที"

"แต่ยังมีอีก"

"คุณกำลังทำให้วงจรของฉันลัดวงจร! มีอะไรอีก"

"เมื่อเรากำหนดค่า int ให้กับตัวแปร Integer เมธอด Integer.valueOf จะเรียกว่า:"

รหัส เกิดอะไรขึ้นจริงๆ
Integer x = 5;
Integer x = Integer.valueOf(5);

"ใช่ ฉันเข้าใจแล้วจากตัวอย่างด้านบน"

"แต่ ฟังก์ชัน valueOf ไม่ได้สร้างวัตถุจำนวนเต็มใหม่เสมอไป"

"เอ่อ คุณหมายความว่าอย่างไร «ไม่เสมอไป»"

"มันแคชค่าตั้งแต่ -128 ถึง 127"

รหัส เกิดอะไรขึ้นจริงๆ คำอธิบาย
Integer x = 300;
Integer y = 300;
Integer z = 300;
Integer x = Integer.valueOf(300);
Integer y = Integer.valueOf(300);
Integer z = Integer.valueOf(300);
ตัวแปร x, y และ z มีการอ้างอิงถึงวัตถุต่างๆ
Integer x = 100;
Integer y = 100;
Integer z = 100;
Integer x = Integer.valueOf(100);
Integer y = Integer.valueOf(100);
Integer z = Integer.valueOf(100);
ตัวแปร x, y และ z มีการอ้างอิงไปยังวัตถุเดียวกัน
Integer x = new Integer(10)
Integer y = new Integer(10)
Integer z = 10;
Integer t = 10;
Integer x = new Integer(10)
Integer y = new Integer(10)
Integer z = Integer.valueOf(10);
Integer t = Integer.valueOf(10);
ตัวแปร z และ t มีการอ้างอิงไปยังวัตถุเดียวกัน

"อีกนัยหนึ่ง สถานการณ์คือ:"

1)  หากเราเขียน «จำนวนเต็มใหม่()» รับประกันว่าเราจะได้วัตถุใหม่

2)  หากเราเรียก Integer.valueOf() อย่างชัดเจนหรือผ่าน autoboxing เมธอดอาจส่งคืนวัตถุใหม่หรือวัตถุที่แคชหากอาร์กิวเมนต์ number อยู่ในช่วงตั้งแต่ -128 ถึง 127

"อะไรที่แย่มากเกี่ยวกับวิธีการส่งคืนวัตถุจากแคช"

"ไม่เป็นไร คุณแค่ต้องรู้ว่าบางครั้งเมื่อคุณไม่คาดคิด วัตถุอาจเท่ากัน ทุกสิ่งที่มีความเท่าเทียมกันนั้นซับซ้อน หากเราเปรียบเทียบสิ่งดั้งเดิมกับสิ่งไม่ดั้งเดิม พวกมันจะถูกเปรียบเทียบเป็นสิ่งดั้งเดิม:"

ปัญหาการเปรียบเทียบ
int x = 300;
Integer y = 300;
Integer z = 300;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //false (comparison based on references)
ตัวอย่างที่น่าสนใจยิ่งขึ้น แคชเข้ารูปภาพที่นี่
int x = 100;
Integer y = 100;
Integer z = 100;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //true (comparison based on references; they point to the same object)
แต่แคชไม่เกี่ยวข้องที่นี่
int x = 100;
Integer y = new Integer(100);
Integer z = 100;

x == y; //true (comparison based on primitive value)
x == z; //true (comparison based on primitive value)
y == z; //false (comparison based on references; they point to different objects)

"เยี่ยมมาก... แล้วฉันจะจำทั้งหมดนี้ได้อย่างไร"

"คุณไม่จำเป็นต้องท่องจำสิ่งนี้ คุณเพียงแค่ต้องเข้าใจว่าทั้งหมดนี้ถูกจัดระเบียบอย่างไร และเกิดอะไรขึ้นจริงเมื่อสิ่งดั้งเดิมและไม่ใช่สิ่งดั้งเดิมเข้ามามีบทบาท"

"ฉันยังแนะนำให้คุณดูที่วิธีการของคลาส Integer มันมีวิธีการที่ดีและมีประโยชน์ค่อนข้างน้อย คุณเคยใช้หนึ่งในนั้นค่อนข้างบ่อยด้วยซ้ำ"

"ใช่ ฉันจำได้ Integer.parseInt();"