在Java语言中,通过覆盖Object类的clone()方法可以实现浅克隆。
1、浅克隆
在浅克隆中,如果原型对象的成员变量是值类型,将复制一份给克隆对象;如果原型对象的成员变量是引用类型,则将引用对象的地址复制一份给克隆对象,也就是说原型对象和克隆对象的成员变量指向相同的内存地址。简单来说,在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。
2、深克隆
在深克隆中,无论原型对象的成员变量是值类型还是引用类型,都将复制一份给克隆对象,深克隆将原型对象的所有引用对象也复制一份给克隆对象。简单来说,在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。
在Java语言中,如果需要实现深克隆,可以通过覆盖Object类的clone()方法实现,也可以通过序列化(Serialization)等方式来实现。(如果引用类型里面还包含很多引用类型,或者内层引用类型的类里面又包含引用类型,使用clone方法就会很麻烦。这时我们可以用序列化的方式来实现对象的深克隆。)
序列化就是将对象写到流的过程,写到流中的对象是原有对象的一个拷贝,而原对象仍然存在于内存中。通过序列化实现的拷贝不仅可以复制对象本身,而且可以复制其引用的成员对象,因此通过序列化将对象写到一个流中,再从流里将其读出来,可以实现深克隆。需要注意的是能够实现序列化的对象其类必须实现Serializable接口,否则无法实现序列化操作。
浅克隆代码示例
student
public class Student implements Cloneable{
private int number;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
//重写Object类下面clone()方法
public Student clone(){
Student stu = null;
try {
stu = (Student)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return stu;
}
}
Adrress
package JavaBean.CloneDemo.ShallowClone;
public class Address {
private String add;
public String getAdd() {
return add;
}
public void setAdd(String add) {
this.add = add;
}
}
主函数
package Main;
import JavaBean.CloneDemo.ShallowClone.Address;
import JavaBean.CloneDemo.ShallowClone.Student;
public class CloneMain {
public static void main(String[] args) {
System.out.println("----------------------浅克隆-----------------------------");
// 浅克隆
Student stu = new Student();
stu.setNumber(123);
Student stu2 = stu.clone();
System.out.println("学生1: "+stu.getNumber()+" - 引用的哈希编码"+stu.hashCode());
System.out.println("学生2: "+stu2.getNumber()+" - 引用的哈希编码"+stu2.hashCode());
stu2.setNumber(1189);
System.out.println("学生1: "+stu.getNumber()+" - 引用的哈希编码"+stu.hashCode());
System.out.println("学生2: "+stu2.getNumber()+" - 引用的哈希编码"+stu2.hashCode());
Address addr1 = new Address();
Student stu3 = new Student();
addr1.setAdd("北京市");
stu3.setNumber(123);
stu3.setAddress(addr1);
Student stu4 = stu3.clone();
System.out.println("学生1: "+stu3.getNumber()+"地址"+stu3.getAddress().getAdd()+" - 地址的哈希编码"+addr1.hashCode()+" - 引用的哈希编码值为"+stu3.hashCode());
System.out.println("学生2: "+stu4.getNumber()+"地址"+stu4.getAddress().getAdd()+" - 地址的哈希编码"+addr1.hashCode()+" - 引用的哈希编码值为"+stu4.hashCode());
addr1.setAdd("河南省");
System.out.println("学生1: "+stu3.getNumber()+"地址"+stu3.getAddress().getAdd()+" - 地址的哈希编码"+addr1.hashCode()+" - 引用的哈希编码值为"+stu3.hashCode());
System.out.println("学生2: "+stu4.getNumber()+"地址"+stu4.getAddress().getAdd()+" - 地址的哈希编码"+addr1.hashCode()+" - 引用的哈希编码值为"+stu4.hashCode());
}
}
----------------------浅克隆-----------------------------
学生1: 123 - 引用的哈希编码1836019240
学生2: 123 - 引用的哈希编码325040804
学生1: 123 - 引用的哈希编码1836019240
学生2: 1189 - 引用的哈希编码325040804
学生1: 123地址北京市 - 地址的哈希编码1173230247 - 引用的哈希编码值为856419764
学生2: 123地址北京市 - 地址的哈希编码1173230247 - 引用的哈希编码值为621009875
学生1: 123地址河南省 - 地址的哈希编码1173230247 - 引用的哈希编码值为856419764
学生2: 123地址河南省 - 地址的哈希编码1173230247 - 引用的哈希编码值为621009875
深克隆代码示例
Student_deep
package JavaBean.CloneDemo.DeepClone;
import JavaBean.CloneDemo.ShallowClone.Address;
/**
* @param
* @Author: Daixt
* @Date: 2022-08-05 11:37
* @return
**/
public class Student_deep implements Cloneable {
private int number;
private Address_deep address;
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Address_deep getAddress() {
return address;
}
public void setAddress(Address_deep address) {
this.address = address;
}
//重写Object类下面clone()方法
public Object clone() {
Student_deep stu = null;
try {
stu = (Student_deep) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
stu.address = (Address_deep)address.clone();
return stu;
}
}
Address_deep
package JavaBean.CloneDemo.DeepClone;
public class Address_deep implements Cloneable{
private String add;
public String getAdd() {
return add;
}
public void setAdd(String add) {
this.add = add;
}
public Object clone(){
Address_deep addr = null;
try {
addr = (Address_deep)super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return addr;
}
}
主函数
package Main;
import JavaBean.CloneDemo.DeepClone.Address_deep;
import JavaBean.CloneDemo.DeepClone.Student_deep;
public class CloneMain {
public static void main(String[] args) {
System.out.println("----------------------深克隆-----------------------------");
//深克隆
Address_deep ad1 = new Address_deep();
Student_deep sd1 = new Student_deep();
ad1.setAdd("深克隆测试");
sd1.setNumber(0001);
sd1.setAddress(ad1);
Student_deep sd2 = (Student_deep) sd1.clone();
System.out.println("学生1: "+sd1.getNumber()+"地址"+sd1.getAddress().getAdd()+" - 地址的哈希编码"+ad1.hashCode()+" - 引用的哈希编码值为"+sd1.hashCode());
System.out.println("学生1: "+sd2.getNumber()+"地址"+sd2.getAddress().getAdd()+" - 地址的哈希编码"+ad1.hashCode()+" - 引用的哈希编码值为"+sd2.hashCode());
ad1.setAdd("深克隆");
System.out.println("学生1: "+sd1.getNumber()+"地址"+sd1.getAddress().getAdd()+" - 地址的哈希编码"+ad1.hashCode()+" - 引用的哈希编码值为"+sd1.hashCode());
System.out.println("学生1: "+sd2.getNumber()+"地址"+sd2.getAddress().getAdd()+" - 地址的哈希编码"+ad1.hashCode()+" - 引用的哈希编码值为"+sd2.hashCode());
}
}
学生1: 1地址深克隆测试 - 地址的哈希编码1265094477 - 引用的哈希编码值为2125039532
学生1: 1地址深克隆测试 - 地址的哈希编码1265094477 - 引用的哈希编码值为312714112
学生1: 1地址深克隆 - 地址的哈希编码1265094477 - 引用的哈希编码值为2125039532
学生1: 1地址深克隆测试 - 地址的哈希编码1265094477 - 引用的哈希编码值为312714112
借鉴:点击跳转