การส่งและส่งคืนรีเฟอเรนซ์
แนะนำใหม่| English | ความหมาย |
|---|---|
| NullPointerException/nʌl ˈpɔɪntə ekˈsepʃn/ | NullPointerException |
การมิวนเตตออบเจ็กต์แตกต่างจากการรีแอสไซน์พารามิเตอร์
- ผู้เรียกใช้ชี้ไปยัง Student ที่มีคะแนน 10 เมทดอดดำเนินการ s.addScore(5); แล้ว s = new Student("Other");
- คะแนนของออบเจ็กต์ร่วมเดิมกลายเป็น 15. การรีแอสไซน์พารามิเตอร์ภายในไม่เปลี่ยนตัวแปรของผู้เรียกใช้ เพราะ Java คัดลอกค่ารีเฟอเรนซ์เข้าไปในพารามิเตอร์
การส่งออบเจ็กต์เข้าไปในเมธอด
- Java คัดลอก ค่ารีเฟอเรนซ์ เข้าไปในพารามิเตอร์เมทดอด; ไม่ได้คัดลอกออบเจ็กต์ พารามิเตอร์ของเมทดอดชี้ไปที่ ออบเจ็กต์เดียวกัน กับตัวแปรของผู้เรียกใช้
- การเปลี่ยนแปลงที่วิธีทำทำให้กับออบเจ็กต์จึง มองเห็นได้โดยผู้เรียกใช้ ทั้งพารามิเตอร์แบบพรีมิทีฟและพารามิเตอร์แบบรีเฟอเรนซ์ถูกส่งผ่านด้วยค่า; รีเฟอเรนซ์ที่ถูกคัดลอกยังสามารถเข้าถึงออบเจ็กต์ร่วมกันได้
พรีมิทีฟเทียบกับออบเจ็กต์ในฐานะอาร์กิวเมนต์
- พารามิเตอร์แบบ พรีมิทีฟ จะถูก คัดลอก — วิธีทำไม่สามารถเปลี่ยนตัวแปรของผู้เรียกใช้ได้ สำหรับพารามิเตอร์ที่เป็นออบเจ็กต์ รีเฟอเรนซ์ที่ถูกคัดลอกจะเข้าถึงออบเจ็กต์เดียวกัน — วิธีทำสามารถแก้ไขข้อมูลของออบเจ็กต์นั้นได้
changeInt(x)ไม่สามารถแก้ไขxได้;student.addScore(10)ทำให้ นักเรียนคนนั้นเปลี่ยนไป ให้ถามว่าวิธีทำกำลังแก้ไขออบเจ็กต์ร่วมกันหรือแค่กำหนดค่าใหม่ให้กับพารามิเตอร์เฉพาะที่เท่านั้น
การส่งคืนออบเจ็กต์
- วิธีทำสามารถ คืนค่ารีเฟอเรนส์ ไปยังออบเจ็กต์ได้ — ผู้เรียกใช้จึงได้แบ่งปันรีเฟอเรนส์นั้น
public Student topStudent() { return best; }คืนค่ารีเฟอเรนส์ไปยังbest - การคืนค่า
bestทำให้มีการแบ่งปันออบเจ็กต์ที่มีอยู่เดิม ในทางตรงกันข้ามreturn new Student("Copy");สร้างออบเจ็กต์ใหม่และคืนค่ารีเฟอเรนส์ของมัน; วิธีทำยังสามารถคืนค่าnullได้อีกด้วย อ่านนิพจน์การคืนค่าก่อนตัดสินใจว่าสถานะถูกแบ่งปันหรือไม่
คัดลอกการอ้างอิง, วัตถุร่วมกัน; คัดลอก primitive
คะแนนของวัตถุเปลี่ยน; โพรมิทีฟ x ไม่เปลี่ยน
เมื่อคุณส่งวัตถุไปยังเมทอด เมทอดจะได้รับ...
Difficulty 1/5 · 100 coins + a small bonus on first completion today
Java คัดลอกค่าการอ้างอิงลงในตัวแปรพารามิเตอร์แยกต่างหาก การอ้างอิงทั้งสองสามารถเข้าถึงออบเจกต์เดียวกันได้; การ reassign พารามิเตอร์จะไม่แทนที่ตัวแปรของผู้เรียกใช้
เมทอดสามารถเปลี่ยนตัวแปร int ของผู้เรียกได้โดยการแก้ไขพารามิเตอร์
Difficulty 1/5 · 100 coins + a small bonus on first completion today
โพรมิทีฟถูกคัดลอก — ตัวแปร int ของผู้เรียกไม่ถูกเปลี่ยนแปลง
การเรียก instance method ผ่าน null reference จะเกิด...
Difficulty 1/5 · 100 coins + a small bonus on first completion today
null ชี้ไปยังออบเจกต์ใดเลย ไม่มีอะไรให้เรียก method บน
method สามารถ return การอ้างอิงไปยังออบเจกต์ ซึ่งผู้เรียกใช้จึงสามารถใช้งานร่วมกันได้
Difficulty 1/5 · 100 coins + a small bonus on first completion today
วิธีหนึ่งสามารถคืนค่าอ้างอิงวัตถุที่มีอยู่เดิมและแบ่งปันวัตถุนั้นให้กับผู้เรียกใช้ วิธีอื่นอาจสร้างและคืนค่าวัตถุใหม่แทนได้
เพื่อใช้งานอ้างอิงที่อาจเป็น null อย่างปลอดภัย คุณควรตรวจสอบ...
Difficulty 1/5 · 100 coins + a small bonus on first completion today
ป้องกันปัญหา null ก่อนเรียกใช้เมทโธดบนมัน
ทุกเมทโธดที่คืนค่าอ้างอิง Student ต้องคืนค่าวัตถุที่มีอยู่เดิมก่อนหน้าเท่านั้น
Difficulty 1/5 · 100 coins + a small bonus on first completion today
ผิด: return new Student("Other"); สร้างและคืนค่าวัตถุใหม่
อ้างอิง null
- รีเฟอเรนส์ที่ชี้ไปที่ ไม่มีออบเจ็กต์ คือ
nullการเรียกใช้วิธีแบบ อินสแตนซ์ ผ่านnullจะเกิดข้อผิดพลาด NullPointerException - การคืนค่า
null(เช่น "ไม่พบ") เป็นเรื่องปกติ — ผู้เรียกใช้ต้องตรวจสอบค่านี้ ต้องป้องกันด้วยif (s != null) { s.addScore(10); }ก่อนใช้งานรีเฟอเรนส์ที่อาจเป็นค่าว่าง
การส่งออบเจ็กต์เป็นการคัดลอกค่ารีเฟอเรนส์ — วิธีทำสามารถเปลี่ยนออบเจ็กต์ของผู้เรียกใช้ได้; การส่งพรีมิทีฟเป็นการคัดลอกค่า — จึงไม่สามารถ改变的ได้ ดังนั้น student.addScore(10) จึงแก้ไขออบเจ็กต์ของผู้เรียกใช้ แต่ changeInt(x) ทำให้ x ของผู้เรียกใช้ไม่เปลี่ยนแปลง และการเรียกใช้วิธีแบบอินสแตนซ์ผ่านรีเฟอเรนส์ null จะเกิดข้อผิดพลาด NullPointerException — ตรวจสอบ != null ก่อนเมื่อรีเฟอเรนส์อาจเป็นค่าว่าง
After the two statements, what is the original caller-referenced Student score?
Difficulty 2/5 · 140 coins + a small bonus on first completion today
The first statement mutates the original object to 15. The later local reassignment does not replace the caller reference.
เมทโธดคืนค่า new Student("Other"); แต่ผู้เรียกใช้ไม่สนใจผลลัพธ์ ตัวแปร Student ที่ผู้เรียกใช้มีอยู่เดิมจะเป็นอย่างไร?
Difficulty 1/5 · 100 coins + a small bonus on first completion today
การคืนค่าอ้างอิงไม่ได้ทำการกำหนดค่าลงในตัวแปรของผู้เรียกใช้ ตัวแปรที่มีอยู่ยังคงชี้ไปยังวัตถุต้นฉบับ
Reference vs. Value:
void addTen(Student s) { s.addScore(10); }— เปลี่ยนออบเจ็กต์ที่ถูกส่ง (shared reference)void addTen(int x) { x += 10; }—intของผู้เรียกใช้ไม่เปลี่ยนแปลง (copied value)- ค่าพารามิเตอร์ทั้งสองถูกคัดลอก; มีเพียงรีเฟอเรนส์ที่ถูกคัดลอกเท่านั้นที่จะเข้าถึงสถานะที่แก้ไขได้ร่วมกัน
ขยายเหตุผลไปยังกรณีใหม่
- เปรียบเทียบ
return s;กับreturn new Student("Other");: ตัวแรกคืนค่าอ้างอิงที่ได้รับ; ตัวที่สองคืน object ที่สร้างขึ้นใหม่ ไม่มีตัวไหนเปลี่ยนตัวแปรของ caller จนกว่า caller จะ assign ผลลัพธ์ - เพื่อทำนายการเปลี่ยนแปลง ให้วาดผู้เรียกใช้และพารามิเตอร์เป็นรีเฟอเรนส์แยกต่างหากที่ชี้ไปยังออบเจ็กต์ อัปเดตออบเจ็กต์สำหรับการเรียกใช้方法的 (mutator) และอัปเดตลูกศรพารามิเตอร์เท่านั้นสำหรับการกำหนดค่าพารามิเตอร์ใหม่
การส่งรีเฟอเรนส์ออบเจ็กต์เป็นการคัดลอกค่าเข้าไปในพารามิเตอร์ ดังนั้นวิธีทำ สามารถเปลี่ยน ออบเจ็กต์ของผู้เรียกใช้ได้; การส่ง พรีมิทีฟ เป็นการคัดลอกค่า ดังนั้นจึง ไม่สามารถ改变的ได้ วิธีทำสามารถ คืนค่ารีเฟอเรนส์ ไปยังออบเจ็กต์ได้ รีเฟอเรนส์ที่ไม่มีออบเจ็กต์คือ null — การเรียกใช้วิธีแบบอินสแตนซ์ผ่านมันจะเกิดข้อผิดพลาด NullPointerException ดังนั้นต้องตรวจสอบก่อน