浅复制
被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。
深复制
被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍(递归下去)。
Java中对象的克隆
Object的clone()方法
clone方法将对象复制了一份并返回给调用者。一般而言,clone()方法满足:
1)对任何的对象x,都有x.clone() !=x
克隆对象与原对象不是同一个对象
2)对任何的对象x,都有x.clone().getClass()= =x.getClass()
克隆对象与原对象的类型一样
3)如果对象x的equals()方法定义恰当,那么x.clone().equals(x)应该成立。
实现:
1)为了获取对象的一份拷贝,我们可以利用Object类的clone()方法。
2)在派生类中覆盖基类的clone()方法,并声明为public(Object类中的clone()方法为protected的)
3)在派生类的clone()方法中,调用super.clone()
4)在派生类中实现Cloneable接口
2)在派生类中覆盖基类的clone()方法,并声明为public(Object类中的clone()方法为protected的)
3)在派生类的clone()方法中,调用super.clone()
4)在派生类中实现Cloneable接口
浅复制
public class Student implements Cloneable {
private int age;
private String name;
private Book book;
public int getAge() {
return age;
}
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public Object clone() throws CloneNotSupportedException {
Object object = super.clone();
return object;
}
}
public class Book {
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Student student1 = new Student();
Book book = new Book();
book.setName("english");
student1.setName("zhangsan");
student1.setAge(22);
student1.setBook(book);
Student student2 = (Student) student1.clone();
System.out.println(student1.clone().equals(student1));// false
System.out.println(student1.clone() == student1);// false
System.out.println(student1.clone().getClass() == student2.getClass());// true
System.out.println(student2.getName());// zhangsan
student1.setName("lisi");
student1.getBook().setName("chinese");
System.out.println(student2.getName());// zhangsan
System.out.println(student2.getBook().getName());// chinese
}
}
深复制
方式一:利用clone方法
public class Fruit implements Cloneable {
public String name;
public Apple apple;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Apple getApple() {
return apple;
}
public void setApple(Apple apple) {
this.apple = apple;
}
@Override
public Object clone() throws CloneNotSupportedException {
<strong>Fruit fruit1 = (Fruit) super.clone();
fruit1.setApple((Apple) fruit1.getApple().clone());
return fruit1;</strong>
}
}
public class Apple implements Cloneable {
public String Name = "";
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
@Override
public Object clone() throws CloneNotSupportedException {
<strong>return super.clone();</strong>
}
}
public class Test {
public static void main(String[] args) throws Exception {
Fruit fruit1 = new Fruit();
Apple apple = new Apple();
fruit1.setName("apple");
apple.setName("fusi");
fruit1.setApple(apple);
Fruit fruit2 = (Fruit) fruit1.clone();
System.out.println(fruit1.clone().equals(fruit1));// false
System.out.println(fruit1.clone() == fruit1);// false
System.out.println(fruit1.clone().getClass() == fruit2.getClass());// true
System.out.println(fruit2.getName());// apple
fruit1.setName("banana");
fruit1.getApple().setName("shandong");
System.out.println(fruit2.getName());// apple
System.out.println(fruit2.getApple().getName());// fusi
}
}
public class People implements Serializable {
public String name;
public Girl girl;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Girl getGirl() {
return girl;
}
public void setGirl(Girl girl) {
this.girl = girl;
}
public Object deepCopy() throws Exception{
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();
}
}
public class Girl implements Serializable {
public String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Test {
public static void main(String[] args) throws Exception {
People people1 = new People();
Girl girl = new Girl();
people1.setName("zhangsan");
girl.setName("meimei");
people1.setGirl(girl);
People people2 = (People) people1.deepCopy();
System.out.println(people1.deepCopy().equals(people1));// false
System.out.println(people1.deepCopy() == people1);// false
System.out.println(people1.deepCopy().getClass() == people2.getClass());// true
System.out.println(people2.getName());// zhangsan
people1.setName("lisi");
people1.getGirl().setName("lili");
System.out.println(people2.getName());// zhangsan
System.out.println(people2.getGirl().getName());// meimei
}
}