Cách triển khai Sao chép nông và Sao chép sâu trong Java



Bài viết này sẽ cung cấp cho bạn kiến ​​thức chi tiết và toàn diện về Shallow Copy và Deep Copy trong Java với các ví dụ.

Nhân bản là một quá trình tạo ra một bản sao hoặc bản sao của đối tượng, phương thức nhân bản Java.lang.Object được sử dụng để tạo bản sao hoặc bản sao của một đối tượng. các đối tượng java triển khai giao diện Cloneable đủ điều kiện để sử dụng phương thức sao chép. Trong bài viết này, chúng ta sẽ thảo luận về Shallow Copy và Deep Copy theo thứ tự sau:

Tạo bản sao của đối tượng Java

Chúng ta có thể tạo một bản sao hoặc bản sao của đối tượng java bằng cách





1. Tạo một bản sao của đối tượng trong một vị trí bộ nhớ khác. Đây được gọi là bản sao sâu.

2. Tạo một tham chiếu mới trỏ đến cùng một vị trí bộ nhớ. Đây còn được gọi là bản sao nông.



Sao chép nông

Việc triển khai mặc định của phương thức clone tạo ra một bản sao cạn của đối tượng nguồn, nó có nghĩa là một thể hiện mới của kiểu Đối tượng được tạo, nó sao chép tất cả các trường vào một thể hiện mới và trả về một đối tượng mới kiểu ‘Đối tượng’. Đối tượng này rõ ràng cần phải được đánh máy trong kiểu đối tượng của đối tượng nguồn.

Đối tượng này sẽ có một bản sao chính xác của tất cả các trường của đối tượng nguồn bao gồm kiểu nguyên thủy và các tham chiếu đối tượng. Nếu đối tượng nguồn chứa bất kỳ tham chiếu nào đến các đối tượng khác trong trường thì trong thể hiện mới sẽ chỉ có tham chiếu đến các đối tượng đó, bản sao của các đối tượng đó sẽ không được tạo. Điều này có nghĩa là nếu chúng ta thực hiện các thay đổi trong bản sao cạn thì các thay đổi sẽ được phản ánh trong đối tượng nguồn. Cả hai trường hợp đều không độc lập.

Phương thức clone trong lớp Object được bảo vệ về bản chất, vì vậy không phải tất cả các lớp đều có thể sử dụng phương thức clone (). Bạn cần triển khai giao diện Cloneable và ghi đè phương thức sao chép. Nếu giao diện Cloneable không được triển khai thì bạn sẽ nhận được CloneNotSupportedException.super.clone () sẽ trả về bản sao nông như mỗi lần triển khai trong lớp Đối tượng.



Mã cho bản sao nông

package com.test class Department {String empId String grade String chỉ định public Department (String empId, String grade, String Desigation) {this.empId = empId this.grade = grade this.designation = Designation}} class Nhân viên triển khai Cloneable {int id Tên chuỗi Phòng ghi nợ công nhân viên (int id, Tên chuỗi, Tên phòng) {this.id = id this.name = name this.dept = dept} // Phiên bản mặc định của phương thức clone (). Nó tạo ra bản sao nông của một đối tượng. bảo vệ Object clone () ném CloneNotSupportedException {return super.clone ()}} public class ShallowCopyInJava {public static void main (String [] args) {Department dept1 = new Department ('1', 'A', 'AVP') Nhân viên emp1 = new Employee (111, 'John', dept1) Employee emp2 = null try {// Tạo bản sao của emp1 và gán nó cho emp2 emp2 = (Employee) emp1.clone ()} catch (CloneNotSupportedException e) {e. printStackTrace ()} // In tên của 'emp1' System.out.println (emp1.dept.designation) // Đầu ra: AVP // Thay đổi tên của 'emp2' emp2.dept.designation = 'Director' // Thay đổi này sẽ được phản ánh trong Nhân viên ban đầu 'emp1' System.out.println (emp1.dept.designation) // Đầu ra: Director}}

Đầu ra:

Output-Shallow-Copy

phương pháp ảo là gì

Trong ví dụ trên, chúng ta có một lớp Nhân viên emp1 có ba biến lớp id (int), tên (Chuỗi) và bộ phận (Department).

Bây giờ chúng tôi sao chép emp1 thành emp2 để tạo một bản sao cạn, sau đó chúng tôi thay đổi chỉ định bằng cách sử dụng đối tượng emp2 và xác minh rằng những thay đổi tương tự cũng được phản ánh trong emp1.


Bản sao sâu

Bản sao sâu của một đối tượng sẽ có một bản sao chính xác của tất cả các trường của đối tượng nguồn giống như bản sao cạn, nhưng không giống như bản sao sallow nếu đối tượng nguồn có bất kỳ tham chiếu nào đến đối tượng dưới dạng các trường, thì bản sao của đối tượng được tạo bằng cách gọi bản sao phương pháp. Điều này có nghĩa là cả đối tượng nguồn và đích đều độc lập với nhau. Mọi thay đổi được thực hiện trong đối tượng nhân bản sẽ không ảnh hưởng đến đối tượng nguồn.

Mã cho bản sao sâu

ví dụ lớp máy quét trong java
package com.test class Department triển khai Cloneable {String empId String grade String Indication public Department (String empId, String grade, String Desigation) {this.empId = empId this.grade = grade this.designation = Designation} // Phiên bản mặc định của clone () phương pháp. được bảo vệ Đối tượng clone () ném lớp CloneNotSupportedException {return super.clone ()}} Nhân viên thực hiện Nhân bản có thể thay đổi {int id String name Department dept public Employee (int id, String name, Department dept) {this.id = id this.name = name this.dept = dept} // Ghi đè phương thức clone () để tạo bản sao sâu của một đối tượng. Đối tượng được bảo vệ clone () ném 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 {// Tạo bản sao của emp1 và gán nó cho emp2 emp2 = (Employee) emp1.clone ()} catch (CloneNotSupportedException e) {e.printStackTrace ()} // In ký hiệu 'emp1' System.out.println (emp1.dept.designation) // Đầu ra: AVP / / Thay đổi chỉ định của 'emp2' emp2.dept.designation = 'Director' // Thay đổi này sẽ được phản ánh trong Nhân viên ban đầu 'emp1' System.out.println (emp1.dept.designation) // Đầu ra: AVP}}

Đầu ra:

Trong ví dụ trên về Bản sao sâu, không giống như bản sao nông, cả hai đối tượng nguồn và đích đều độc lập với nhau. Bất kỳ thay đổi nào được thực hiện trong emp2 sẽ không ảnh hưởng đến emp1.

Sự khác biệt giữa Bản sao nông và Bản sao sâu

Sao chép nông Bản sao sâu
Đối tượng nhân bản và đối tượng nguồn không hoàn toàn rời rạcĐối tượng nhân bản và đối tượng nguồn hoàn toàn độc lập với nhau.
Các thay đổi được thực hiện trong phiên bản sao chép sẽ tác động đến biến tham chiếu của đối tượng nguồnCác thay đổi được thực hiện trong phiên bản sao chép sẽ không ảnh hưởng đến biến tham chiếu của đối tượng nguồn.
Phiên bản mặc định của bản sao là bản sao cạnĐể tạo bản sao sâu, chúng ta cần ghi đè phương thức nhân bản của lớp Object.
Bản sao nông được ưu tiên nếu các biến lớp của đối tượng chỉ là kiểu nguyên thủy dưới dạng các trườngBản sao sâu được ưu tiên nếu các biến lớp của đối tượng có tham chiếu đến các đối tượng khác dưới dạng trường.
Nó tương đối nhanhNó tương đối chậm.

Với điều này, chúng ta sẽ đến phần cuối của bài viết Shallow Copy và Deep Copy. Tôi hy vọng bạn hiểu được sự khác biệt khác nhau giữa hai loại.

Kiểm tra của Edureka, một công ty học trực tuyến đáng tin cậy với mạng lưới hơn 250.000 người học hài lòng trải dài trên toàn cầu. Khóa đào tạo và cấp chứng chỉ về Java J2EE và SOA của Edureka được thiết kế cho sinh viên và các chuyên gia muốn trở thành Nhà phát triển Java.

Có một câu hỏi cho chúng tôi? Vui lòng đề cập đến vấn đề này trong phần nhận xét của blog “Bản sao nông và Bản sao sâu” này và chúng tôi sẽ liên hệ lại với bạn trong thời gian sớm nhất.