浅拷贝(Shallow Copy)
对于基本数据类型的成员变量,会将原对象的值复制一份给新对象(两部分独立存在,一个改变另一个不受影响);对于引用类型的成员变量,只会拷贝引用地址(仍指向原对象,一个改变另一个也会改变)
1. 通过拷贝构造方法实现浅拷贝
Person
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {
private int age;
private String name;
private Classes classes;
// 拷贝构造方法
public Person(Person person) {
this.age = person.age;
this.name = person.name;
this.classes = person.classes;
}
}
Classes
@Data
@AllArgsConstructor
public class Classes {
private String name;
}
测试
public class Test {
public static void main(String[] args) {
Classes c = new Classes("1班");
Person p1 = new Person(12, "张三", c);
System.out.println(p1); // 12,张三,1班
// 浅拷贝
Person p2 = new Person(p1);
// 尝试更改
p1.setAge(10);
p1.setName("李四");
c.setName("2班");
System.out.println(p2); // 12,张三,2班
}
}
2.通过重写clone()方法进行浅拷贝:
Person
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person implements Cloneable{
private int age;
private String name;
private Classes classes;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
Classes
@Data
@AllArgsConstructor
public class Classes {
private String name;
}
测试
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Classes c = new Classes("1班");
Person p1 = new Person(12, "张三", c);
System.out.println(p1); // 12,张三,1班
// 浅拷贝
Person p2 = (Person) p1.clone();
// 尝试更改
p1.setAge(10);
p1.setName("李四");
c.setName("2班");
System.out.println(p2); // 12,张三,2班
}
}
深拷贝(Deep Copy)
对整个对象进行拷贝(与原对象相互独立,一个改变另一个不受影响)
1.通过重写clone方法来实现深拷贝
重写每个引用类型的成员变量的Clone方法
Person
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person implements Cloneable {
private int age;
private String name;
private Classes classes;
@Override
protected Object clone() throws CloneNotSupportedException {
Person p = (Person) super.clone();
p.classes = (Classes) classes.clone();
return p;
}
}
Classes
@Data
@AllArgsConstructor
public class Classes implements Cloneable {
private String name;
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
测试
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Classes c = new Classes("1班");
Person p1 = new Person(12, "张三", c);
System.out.println(p1); // 12,张三,1班
// 深拷贝
Person p2 = (Person) p1.clone();
// 尝试更改
p1.setAge(10);
p1.setName("李四");
c.setName("2班");
System.out.println(p2); // 12,张三,1班
}
}
2. 通过对象序列化实现深拷贝
Person
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person implements Serializable {
private int age;
private String name;
private Classes classes;
public Object deepClone() throws IOException, ClassNotFoundException {
// 序列化
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);
oos.writeObject(this);
// 反序列化
ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bis);
return ois.readObject();
}
}
Classes
@Data
@AllArgsConstructor
public class Classes implements Serializable {
private String name;
}
测试
public class Test {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Classes c = new Classes("1班");
Person p1 = new Person(12, "张三", c);
System.out.println(p1); // 12,张三,1班
// 深拷贝
Person p2 = (Person) p1.deepClone();
// 尝试更改
p1.setAge(10);
p1.setName("李四");
c.setName("2班");
System.out.println(p2); // 12,张三,1班
}
}