วิธีการใช้งาน Shallow Copy และ Deep Copy ใน Java

บทความนี้จะให้ความรู้โดยละเอียดและครอบคลุมเกี่ยวกับ Shallow Copy และ Deep Copy ใน Java พร้อมตัวอย่าง

การโคลนเป็นกระบวนการสร้างแบบจำลองหรือสำเนา object, clone method Java.lang.Object ใช้ในการสร้างสำเนาหรือจำลองของออบเจ็กต์ วัตถุ java ที่ใช้อินเทอร์เฟซ Cloneable มีสิทธิ์สำหรับการใช้วิธีโคลน ในบทความนี้เราจะพูดถึง Shallow Copy และ 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}}

เอาท์พุต:

Output-Shallow-Copy

นักพัฒนา 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

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