การโคลนเป็นกระบวนการสร้างแบบจำลองหรือสำเนา object, clone method Java.lang.Object ใช้ในการสร้างสำเนาหรือจำลองของออบเจ็กต์ วัตถุ java ที่ใช้อินเทอร์เฟซ Cloneable มีสิทธิ์สำหรับการใช้วิธีโคลน ในบทความนี้เราจะพูดถึง Shallow Copy และ Deep Copy ตามลำดับต่อไปนี้:
- การสร้าง Copy of Java Object
- สำเนาตื้นคืออะไร?
- Deep Copy คืออะไร?
- ความแตกต่างระหว่างสำเนาตื้นและสำเนาลึก
การสร้าง Copy of Java Object
เราสามารถสร้างแบบจำลองหรือสำเนาของวัตถุ java โดย
1. การสร้างสำเนาของวัตถุในตำแหน่งหน่วยความจำอื่น สิ่งนี้เรียกว่า Deep copy
2. สร้างการอ้างอิงใหม่ที่ชี้ไปยังตำแหน่งหน่วยความจำเดียวกัน เรียกอีกอย่างว่าสำเนาตื้น
สำเนาตื้น
การใช้วิธีการโคลนเริ่มต้นจะสร้างสำเนาตื้นของวัตถุต้นทางซึ่งหมายความว่ามีการสร้างอินสแตนซ์ใหม่ของประเภทวัตถุโดยจะคัดลอกฟิลด์ทั้งหมดไปยังอินสแตนซ์ใหม่และส่งคืนวัตถุใหม่ประเภท 'วัตถุ' ออบเจ็กต์นี้ต้องเป็นแบบพิมพ์ในประเภทวัตถุของวัตถุต้นทางอย่างชัดเจน
อ็อบเจ็กต์นี้จะมีสำเนาที่ถูกต้องของฟิลด์ทั้งหมดของอ็อบเจ็กต์ต้นทางรวมทั้งประเภทดั้งเดิมและการอ้างอิงอ็อบเจ็กต์ หากออบเจ็กต์ต้นทางมีการอ้างอิงถึงอ็อบเจ็กต์อื่น ๆ ในฟิลด์ดังนั้นในอินสแตนซ์ใหม่จะมีเฉพาะการอ้างอิงถึงอ็อบเจ็กต์เหล่านั้นจะไม่มีการสร้างสำเนาของอ็อบเจ็กต์เหล่านั้น ซึ่งหมายความว่าหากเราทำการเปลี่ยนแปลงในสำเนาตื้นการเปลี่ยนแปลงจะสะท้อนในวัตถุต้นทาง อินสแตนซ์ทั้งสองไม่เป็นอิสระ
วิธีการโคลนในคลาส Object ได้รับการป้องกันตามธรรมชาติดังนั้นไม่ใช่ทุกคลาสที่สามารถใช้เมธอด clone () ได้ คุณต้องใช้อินเทอร์เฟซ Cloneable และแทนที่วิธีการโคลน หากไม่ได้ใช้อินเทอร์เฟซ Cloneable คุณจะได้รับ CloneNotSupportedException.super.clone () จะส่งคืนสำเนาตื้นตามการนำไปใช้ในคลาส Object
รหัสสำหรับสำเนาตื้น
package com.test class Department {String empId String grade String designation public Department (String empId, String grade, String designation) {this.empId = empId this.grade = grade this.designation = designation}} class Employee implements Cloneable {int id ชื่อสายอักขระ Department dept public Employee (int id, String name, Department dept) {this.id = id this.name = name this.dept = dept} // เวอร์ชันเริ่มต้นของวิธีการ clone () สร้างสำเนาของวัตถุแบบตื้น ๆ โคลนวัตถุที่มีการป้องกัน () พ่น CloneNotSupportedException {return super.clone ()}} คลาสสาธารณะ ShallowCopyInJava {public static void main (String [] args) {Department dept1 = new Department ('1', 'A', 'AVP') พนักงาน emp1 = พนักงานใหม่ (111, 'John', dept1) Employee emp2 = null try {// การสร้างโคลนของ emp1 และกำหนดให้ emp2 emp2 = (Employee) emp1.clone ()} catch (CloneNotSupportedException e) {e. printStackTrace ()} // การพิมพ์ชื่อ 'emp1' System.out.println (emp1.dept.designation) // Output: AVP // การเปลี่ยนชื่อ 'emp2' emp2.dept.designation = 'Director' // การเปลี่ยนแปลงนี้จะแสดงในระบบ 'emp1' ของพนักงานดั้งเดิม (emp1.dept.designation) // Output: Director}}
เอาท์พุต:
นักพัฒนา python ระดับเริ่มต้นดำเนินการต่อ
ในตัวอย่างข้างต้นเรามีคลาสพนักงาน emp1 ซึ่งมี 3 class variable id (int), name (String) และ department (Department)
ตอนนี้เราโคลน emp1 เป็น emp2 เพื่อสร้างสำเนาตื้นหลังจากนั้นเราเปลี่ยนการกำหนดโดยใช้อ็อบเจกต์ emp2 และตรวจสอบว่าการเปลี่ยนแปลงเดียวกันได้สะท้อนให้เห็นใน emp1 ด้วย
สำเนาลึก
สำเนาลึกของวัตถุจะมีสำเนาที่ถูกต้องของฟิลด์ทั้งหมดของวัตถุต้นทางเช่นสำเนาตื้น แต่ต่างจากสำเนาที่มีขนาดเล็กหากวัตถุต้นทางมีการอ้างอิงถึงวัตถุเป็นเขตข้อมูลจากนั้นแบบจำลองของวัตถุจะถูกสร้างขึ้นโดยการเรียกโคลน วิธี. ซึ่งหมายความว่าวัตถุต้นทางและปลายทางทั้งสองเป็นอิสระจากกัน การเปลี่ยนแปลงใด ๆ ที่เกิดขึ้นในวัตถุที่ถูกโคลนจะไม่ส่งผลกระทบต่อวัตถุต้นทาง
รหัสสำหรับ Deep Copy
fibonacci c ++ เรียกซ้ำ
แพคเกจ com.test class Department ใช้ Cloneable {String empId String grade String designation public Department (String empId, String grade, String designation) {this.empId = empId this.grade = grade this.designation = designation} // เวอร์ชันเริ่มต้นของโคลน () วิธี. Protected Object clone () พ่น CloneNotSupportedException {return super.clone ()}} class พนักงานใช้ Cloneable {int id String name Department dept public Employee (int id, String name, Department dept) {this.id = id this.name = name this.dept = dept} // วิธีการแทนที่ clone () เพื่อสร้างสำเนาลึกของวัตถุ Protected Object clone () พ่น CloneNotSupportedException {Employee emp = (Employee) super.clone () emp.dept = (Department) dept.clone () return emp}} public class DeepCopyInJava {public static void main (String [] args) { Department dept1 = new Department ('1', 'A', 'AVP') Employee emp1 = new Employee (111, 'John', dept1) Employee emp2 = null try {// การสร้างโคลนของ emp1 และกำหนดให้กับ emp2 emp2 = (พนักงาน) emp1.clone ()} catch (CloneNotSupportedException e) {e.printStackTrace ()} // การพิมพ์การกำหนด 'emp1' System.out.println (emp1.dept.designation) // เอาต์พุต: AVP / / การเปลี่ยนชื่อของ 'emp2' emp2.dept.designation = 'Director' // การเปลี่ยนแปลงนี้จะแสดงใน Employee 'emp1' System.out.println (emp1.dept.designation) // Output: AVP}}
เอาท์พุต:
ในตัวอย่างข้างต้นของ Deep copy ซึ่งแตกต่างจากสำเนาตื้นทั้งวัตถุต้นทางและปลายทางจะเป็นอิสระจากกัน การเปลี่ยนแปลงใด ๆ ที่เกิดขึ้นใน emp2 จะไม่ส่งผลกระทบต่อ emp1
ความแตกต่างระหว่างสำเนาตื้นและสำเนาลึก
สำเนาตื้น | สำเนาลึก |
วัตถุที่โคลนและวัตถุต้นทางจะไม่ปะติดปะต่อกันอย่างสมบูรณ์ | วัตถุที่โคลนและวัตถุต้นทางเป็นอิสระจากกันโดยสิ้นเชิง |
การเปลี่ยนแปลงที่เกิดขึ้นในอินสแตนซ์ที่โคลนจะส่งผลต่อตัวแปรอ้างอิงของออบเจ็กต์ต้นทาง | การเปลี่ยนแปลงที่เกิดขึ้นในอินสแตนซ์โคลนจะไม่ส่งผลกระทบต่อตัวแปรอ้างอิงของวัตถุต้นทาง |
เวอร์ชันเริ่มต้นของโคลนคือสำเนาตื้น | ในการสร้างสำเนาลึกเราจำเป็นต้องแทนที่วิธีการโคลนของคลาส Object |
ต้องการคัดลอกแบบตื้นหากตัวแปรคลาสของอ็อบเจ็กต์เป็นประเภทดั้งเดิมเท่านั้นเป็นฟิลด์ | ขอแนะนำให้ใช้สำเนาลึกหากตัวแปรคลาสของออบเจ็กต์มีการอ้างอิงถึงออบเจ็กต์อื่นเป็นฟิลด์ |
ค่อนข้างเร็ว | ค่อนข้างช้า |
ด้วยเหตุนี้เราจึงมาถึงตอนท้ายของบทความ Shallow Copy และ Deep Copy ฉันหวังว่าคุณจะเข้าใจถึงความแตกต่างที่หลากหลายระหว่างทั้งสอง
ตรวจสอบไฟล์ โดย Edureka บริษัท การเรียนรู้ออนไลน์ที่เชื่อถือได้ซึ่งมีเครือข่ายผู้เรียนที่พึงพอใจมากกว่า 250,000 คนกระจายอยู่ทั่วโลก หลักสูตรการฝึกอบรมและการรับรอง Java J2EE และ SOA ของ Edureka ออกแบบมาสำหรับนักเรียนและผู้เชี่ยวชาญที่ต้องการเป็น Java Developer
มีคำถามสำหรับเรา? โปรดระบุไว้ในส่วนความคิดเห็นของบล็อก 'สำเนาตื้นและสำเนาลึก' และเราจะติดต่อกลับโดยเร็วที่สุด