JavaRush /จาวาบล็อก /Random-TH /ความแตกต่างระหว่างตัวสร้างและวิธีการทั่วไป
fog
ระดับ

ความแตกต่างระหว่างตัวสร้างและวิธีการทั่วไป

เผยแพร่ในกลุ่ม
ตัวสร้างเป็นวิธีการพิเศษที่มีจุดประสงค์เพื่อตั้งค่าของฟิลด์ของวัตถุในขั้นต้น เมื่อมองแวบแรก ตัวสร้างวัตถุไม่ได้แตกต่างจากวิธีวัตถุทั่วไปมากนัก และแท้จริงแล้ว ภายใน Constructor เราสามารถทำทุกอย่างที่เราสามารถทำได้ในวิธีอ็อบเจ็กต์ปกติ: ส่งข้อความไปยังคอนโซล เข้าถึงฟิลด์และวิธีการทั้งหมดของอ็อบเจ็กต์ใหม่ ส่งข้อยกเว้น และอื่นๆ เช่นเดียวกับวิธีการปกติ ตัวสร้างสามารถมีอาร์กิวเมนต์ได้ เช่นเดียวกับวิธีการโอเวอร์โหลด อาจมีตัวสร้างหลายตัวที่มีลายเซ็นต่างกัน เช่นเดียวกับวิธีการทั่วไป ตัวสร้างสามารถกำหนดพารามิเตอร์ตามตัวแปรประเภทได้ แม้ว่าเราจะดู bytecode ที่สร้างโดยคอมไพลเลอร์ ในจุดที่ควรมีการเรียกตัวสร้าง เราจะพบการเรียกไปยังวิธีการบางอย่างที่มีชื่อที่การเรียกนั้นไม่แตกต่างจากการเรียกไปยังวิธีอื่น ๆ<init>ของ วัตถุ. และเมื่อพบ bytecode ของวิธีนี้แล้ว เราจะพบว่ามันมีผลจากการคอมไพล์ Constructor ของเรา ดูเหมือนว่าจะมีความแตกต่างไม่มากจากวิธีการทั่วไป แต่มีอยู่และมีความสำคัญมาก ก่อนอื่น ลองคิดดูก่อนว่าเหตุใดเราจึงต้องมีตัวสร้างจริง ๆ ในการจัดเก็บและประมวลผลข้อมูลใดๆ ไม่ว่าจะเป็นประเภทพื้นฐาน อาร์เรย์ หรืออ็อบเจ็กต์ เราจำเป็นต้องมีหน่วยความจำจำนวนหนึ่ง นี่อาจเป็นการลงทะเบียนตัวประมวลผล พื้นที่สแต็ก หรือพื้นที่บางส่วนที่จัดสรรไว้ในส่วนข้อมูลกระบวนการ หรือในส่วนที่จัดสรรแบบไดนามิกของหน่วยความจำ (ฮีป) ในภาษาการเขียนโปรแกรมหลายภาษา เพื่อจุดประสงค์ในการเร่งความเร็ว เมื่อโปรแกรมร้องขอหน่วยความจำชิ้นใหม่ หน่วยความจำนั้นไม่ได้ถูกเคลียร์ให้กับโปรแกรม และอาจมีข้อมูลที่กำหนดเองซึ่งจัดเก็บไว้ในเซลล์หน่วยความจำนี้ก่อนหน้านี้ การเตรียมและการเขียนค่าที่จำเป็นลงในหน่วยความจำเพื่อที่ว่าในที่สุดจะมีโครงสร้างข้อมูลที่มีความหมายบางส่วนก็ตกลงไปบนไหล่ของโปรแกรมเมอร์ ค่อนข้างเป็นธรรมชาติที่โปรแกรมเมอร์ต้องการทำให้ชีวิตของพวกเขาง่ายขึ้นและเขียนรูทีนเพื่อเริ่มต้น (นั่นคือ ตั้งค่าเริ่มต้น) สำหรับโครงสร้างข้อมูลที่ใช้บ่อย รู ทีนดังกล่าวถูกใช้เกือบตลอดเวลา ดังนั้นผู้สร้างภาษาจาวาจึงตัดสินใจบังคับให้รูทีนการเริ่มต้นดังกล่าวจำเป็นต้องเรียกใช้เมื่อสร้างวัตถุ และเรียกพวกมันว่าคอนสตรัคเตอร์ เมื่อสร้างอ็อบเจ็กต์ใหม่ใน Java สิ่งต่อไปนี้จะเกิดขึ้น: ขั้นแรก ตัวจัดการหน่วยความจำ Java จะจัดสรรจำนวนหน่วยความจำที่จำเป็นเพื่อรองรับอ็อบเจ็กต์ ในกรณีนี้ ไม่เพียงแต่คำนึงถึงฟิลด์ที่ประกาศโดยตรงในคลาสของออบเจ็กต์ที่สร้างขึ้นเท่านั้น แต่ยังรวมถึงฟิลด์ที่ประกาศในบรรพบุรุษทั้งหมดของคลาสนี้ด้วย นอกจากนี้ วอลุ่มนี้ยังมีพื้นที่สำหรับวางโครงสร้างที่เครื่อง Java ใช้สำหรับความต้องการภายใน ฟิลด์ทั้งหมดของ "ว่าง" ดังกล่าวจะถูกตั้งค่าเป็นค่าเริ่มต้นโดยอัตโนมัติ - nullสำหรับประเภทการอ้างอิง0สำหรับตัวเลขและfalseสำหรับboolean. หลังจากนี้ตัวสร้างคลาสจะถูกเรียกโดยอัตโนมัติซึ่งมีหน้าที่ในการตั้งค่าเริ่มต้นของฟิลด์ของวัตถุ ในขณะที่วิธีปกติคำสั่งแรกสามารถเป็นอะไรก็ได้ แต่ Constructor มีอิสระน้อยกว่ามาก คำสั่งแรกของ Constructor จะต้องเป็นการเรียก Constructor อื่นในคลาสเดียวกันอย่างชัดเจน หรือการเรียก Constructor ของคลาสพาเรนต์โดยชัดแจ้งหรือโดยนัย การเรียกตัวสร้างคลาสเดียวกันที่ชัดเจนนั้นทำโดยใช้คีย์เวิร์ดthisตามด้วยชุดอาร์กิวเมนต์ที่อยู่ในวงเล็บ การเรียก Constructor ของคลาสพาเรนต์อย่างชัดเจนนั้นทำได้ในลักษณะเดียวกันทุกประการ แต่มีการใช้superคีย์เวิร์ด ในอาร์กิวเมนต์ของการเรียก Constructor ของคลาสเดียวกันหรือคลาสพาเรนต์อย่างชัดเจน คุณไม่สามารถเข้าถึงฟิลด์และวิธีการของอ็อบเจ็กต์ได้ เช่นเดียวกับการใช้คีย์เวิร์ดthisและsuperเนื่องจากการเรียก Constructor อย่างชัดเจนทำให้เกิดบริบทคงที่ หากต้องการเรียก Constructor ของคลาสพาเรนต์โดยปริยาย คุณไม่จำเป็นต้องเขียนอะไรเลย แต่ Constructor เริ่มต้นจะถูกเรียกโดยปริยาย ซึ่งจะต้องมีอยู่และมองเห็นได้ในคลาสปัจจุบัน ในเวลาเดียวกัน ควรระลึกไว้ว่าหากสายการเรียกตัวสร้างหลักถูกขัดจังหวะก่อนที่ตัวสร้างคลาสที่อยู่ด้านบนสุดของObjectสายโซ่จะทำงานให้เสร็จสิ้นได้สำเร็จ วัตถุนั้นจะไม่สามารถสรุปได้ นั่นคือ วิธีการfinalize()ของวัตถุดังกล่าวจะไม่มีวันถูกเรียก หลังจากที่ตัวสร้างคลาสพาเรนต์เสร็จสมบูรณ์ การควบคุมจะถูกถ่ายโอนโดยปริยายไปยังบล็อกตัวเริ่มต้นอินสแตนซ์และตัวเริ่มต้นฟิลด์อินสแตนซ์ของคลาสปัจจุบัน ตัวเตรียมใช้งานจะดำเนินการตามลำดับที่ปรากฏในข้อความของโปรแกรม หลังจากที่ตัวเริ่มต้นทำงานเสร็จแล้วเท่านั้น การควบคุมจะถูกถ่ายโอนไปยังส่วนที่เหลือของตัวสร้าง คุณสมบัติที่เหลือของตัวสร้างเกี่ยวข้องกับโมเดลหน่วยความจำ Java หากคลาสหรือบรรพบุรุษของคลาสนั้นfinalize()แทนที่เมธอด ความสมบูรณ์ของ Constructor จะเกิดขึ้นก่อนที่เมธอดจะรัน ( เกิดขึ้น-ก่อนfinalize() ) หากเธรดใดๆ เห็นการอ้างอิงถึงอ็อบเจ็กต์หลังจากที่ Constructor เสร็จสมบูรณ์แล้ว ก็รับประกันได้ว่าเธรดนี้จะเห็นฟิลด์ที่เตรียมใช้งานอย่างถูกต้องfinalของอ็อบเจ็กต์ ซึ่งการกำหนดค่าเริ่มต้นนั้นเกิดขึ้นก่อนที่ Constructor จะเสร็จสิ้น
ความคิดเห็น
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION