什么是深拷贝?用 Java 的例子解释一下。
在内存中创建现有对象的精确副本称为克隆。
类 java.lang.Object 的 clone() 方法接受一个对象作为参数,创建并返回它的副本(克隆)。
为了使用此方法,您需要确保您的类实现了 Cloneable 接口。
示例
import java.util.Scanner; public class CloneExample implements Cloneable { private String name; private int age; public CloneExample(String name, int age){ this.name = name; this.age = age; } public void displayData(){ System.out.println("Name : "+this.name); System.out.println("Age : "+this.age); } public static void main(String[] args) throws CloneNotSupportedException { Scanner sc =new Scanner(System.in); System.out.println("Enter your name "); String name = sc.next(); System.out.println("Enter your age "); int age = sc.nextInt(); CloneExample std = new CloneExample(name, age); System.out.println("Contents of the original object"); std.displayData(); System.out.println("Contents of the copied object"); CloneExample copiedStd = (CloneExample) std.clone(); copiedStd.displayData(); } }
输出
Enter your name Krishna Enter your age 20 Contents of the original object Name : Krishna Age : 20 Contents of the copied object Name : Krishna Age : 20
浅拷贝
每当您尝试使用浅拷贝创建对象的副本时,原始对象的全部字段都会被精确复制。但是,如果它包含任何对象作为字段,则只复制对这些对象的引用,而不是完整的对象。
这意味着,如果您对包含任何对象作为字段的对象执行浅拷贝,由于浅拷贝中只复制了引用,因此原始对象和复制对象在内部指向相同的引用,并且,如果您使用复制对象对数据进行任何更改,它们也会反映在原始对象中。
注意 - 默认情况下,clone() 方法执行浅拷贝。
深拷贝
每当您尝试创建对象的副本时,在深拷贝中,原始对象的全部字段都会被精确复制,此外,如果它包含任何对象作为字段,则也会创建这些对象的副本(使用 clone() 方法)。
这意味着,如果您对包含引用(对象)的对象执行深拷贝,则原始对象和复制对象引用不同的对象,并且,如果您对复制对象的数据进行任何更改,则不会反映在原始对象中。
执行字段复制
覆盖 clone 方法,并在其中使用 clone() 方法复制引用字段,如下所示:
protected Object clone() throws CloneNotSupportedException{ StudentData student = (StudentData) super.clone(); student.contact = (Contact) contact.clone(); return student; }
示例
在下面的示例中,StudentData 类包含一个字符串变量(name),一个整数变量(age)和一个对象(Contact)。
在 main 方法中,我们正在创建 StudentData 类的对象并复制它。从复制的对象中,我们正在更改所用引用的数据(字段值)(Contact 对象)。然后,我们首先打印复制对象的数据,然后打印原始对象的数据。
由于我们进行了深拷贝(通过覆盖 clone() 方法),您可以观察到所做的更改不会反映在原始对象中。
import java.util.Scanner; class Contact implements Cloneable{ private long phoneNo; private String email; private String address; public void setPhoneNo(long phoneNo) { this.phoneNo = phoneNo; } public void setEmail(String email) { this.email = email; } public void setAddress(String address) { this.address = address; } Contact(long phoneNo, String email, String address ){ this.phoneNo = phoneNo; this.email = email; this.address = address; } public void displayContact() { System.out.println("Phone no: "+this.phoneNo); System.out.println("Email: "+this.email); System.out.println("Address: "+this.address); } protected Object clone() throws CloneNotSupportedException{ return super.clone(); } } public class StudentData implements Cloneable { private String name; private int age; private Contact contact; public StudentData(String name, int age, Contact contact){ this.name = name; this.age = age; this.contact = contact; } public void displayData(){ System.out.println("Name : "+this.name); System.out.println("Age : "+this.age); contact.displayContact(); } protected Object clone() throws CloneNotSupportedException{ StudentData student = (StudentData) super.clone(); student.contact = (Contact) contact.clone(); return student; } public static void main(String[] args) throws CloneNotSupportedException { Scanner sc =new Scanner(System.in); System.out.println("Enter your name "); String name = sc.next(); System.out.println("Enter your age "); int age = sc.nextInt(); System.out.println("#############Contact details#############"); System.out.println("Enter your phone number: "); long phoneNo = sc.nextLong(); System.out.println("Enter your Email ID: "); String email = sc.next(); System.out.println("Enter your address: "); String address = sc.next(); System.out.println(" "); //Creating an object of the class StudentData std = new StudentData(name, age, new Contact(phoneNo, email, address)); //Creating a clone of the above object StudentData copiedStd = (StudentData) std.clone(); //Modifying the data of the contact object copiedStd.contact.setPhoneNo(000000000); copiedStd.contact.setEmail("XXXXXXXXXX"); copiedStd.contact.setAddress("XXXXXXXXXX"); System.out.println("Contents of the copied object::"); copiedStd.displayData(); System.out.println(" "); System.out.println("Contents of the original object::"); std.displayData(); } }
输出
Enter your name Krishna Enter your age 20 #############Contact details############# Enter your phone number: 9848022338 Enter your Email ID: [email protected] Enter your address: Hyderabad Contents of the copied object:: Name : Krishna Age : 20 Phone no: 0 Email: XXXXXXXXXX Address: XXXXXXXXXX Contents of the original object:: Name : Krishna Age : 20 Phone no: 9848022338 Email: [email protected] Address: Hyderabad
广告