clone()是Object类的protected 方法,只有实现了Cloneable接口的类,才可以调用clone()方法。
1.浅复制
Lover.java
package zh.clone.demo; public class Lover { private String name; private int age; private char sex; public Lover() { } public Lover(String name, int age, char sex) { super(); this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } @Override public String toString() { return "Lover [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } }
Person.java
package zh.clone.demo; // 实现Cloneable接口 public class Person implements Cloneable{ private String name; private int age; private char sex; private Lover lover; public Person() { } public Person(String name, int age, char sex, Lover lover) { super(); this.name = name; this.age = age; this.sex = sex; this.lover = lover; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public Lover getLover() { return lover; } public void setLover(Lover lover) { this.lover = lover; } // 重写clone(),权限修饰符改为public @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", sex=" + sex + ", lover=" + lover + "]"; } }
CloneDemo1.java
package zh.clone.demo; /* * 浅复制:只复制了基本数据类型和String类型的数据,并没有复制内部对象。 * 因此,复制品修改基本数据类型和String类型的数据,不会影响原来对象对应的数据。 * 但是,复制品修改内部对象的数据,会修改原来对象对应的数据。 */ public class CloneDemo1 { public static void main(String[] args) throws Exception { Lover lover = new Lover("小龙女", 18, '女'); Person person = new Person("杨过", 17, '男', lover); // person只有实现了Cloneable接口,才可以调用clone() Person personCopy = (Person) person.clone(); System.out.println(personCopy); System.out.println(person); //Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]] //Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]] // personCopy修改"基本数据类型和String类型的数据",不会改变person对应的数据 personCopy.setName("神雕大侠"); personCopy.setAge(36); personCopy.setSex('M'); System.out.println(personCopy); System.out.println(person); //Person [name=神雕大侠, age=36, sex=M, lover=Lover [name=小龙女, age=18, sex=女]] //Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]] // personCopy修改"内部对象的数据",会影响person对应的数据 personCopy.getLover().setName("神仙姐姐"); personCopy.getLover().setAge(37); personCopy.getLover().setSex('F'); System.out.println(personCopy); System.out.println(person); //Person [name=神雕大侠, age=36, sex=M, lover=Lover [name=神仙姐姐, age=37, sex=F]] //Person [name=杨过, age=17, sex=男, lover=Lover [name=神仙姐姐, age=37, sex=F]] } }
结论:浅复制不能达到复制品与原来对象完全分离的目的,复制品内部对象的变化,会引起原来对象相应的内部对象的变化。
2.深复制
Lover.java
package zh.clone.demo; // 实现Cloneable接口 public class Lover implements Cloneable{ private String name; private int age; private char sex; public Lover() { } public Lover(String name, int age, char sex) { super(); this.name = name; this.age = age; this.sex = sex; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } // 重写clone(),权限修饰符改为public @Override public Lover clone() throws CloneNotSupportedException { return (Lover) super.clone(); } @Override public String toString() { return "Lover [name=" + name + ", age=" + age + ", sex=" + sex + "]"; } }
Person.java
package zh.clone.demo; // 实现Cloneable接口 public class Person implements Cloneable{ private String name; private int age; private char sex; private Lover lover; public Person() { } public Person(String name, int age, char sex, Lover lover) { super(); this.name = name; this.age = age; this.sex = sex; this.lover = lover; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getSex() { return sex; } public void setSex(char sex) { this.sex = sex; } public Lover getLover() { return lover; } public void setLover(Lover lover) { this.lover = lover; } // 重写clone(),权限修饰符改为public @Override public Person clone() throws CloneNotSupportedException { Person personCopy = (Person) super.clone(); // 实现深复制,则要对内部的每一个对象进行复制 // this.getLover().clone():对原来对象的内部对象进行复制 // 因此,要求原来对象的内部对象也要实现Cloneable接口 personCopy.setLover(this.getLover().clone()); return personCopy; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", sex=" + sex + ", lover=" + lover + "]"; } }
CloneDemo2.java
package zh.clone.demo; /* * 深复制:复制了原来对象的所有数据。 * 复制品的任何改变,都不会影响原来对象的数据。 */ public class CloneDemo2 { public static void main(String[] args) throws Exception { Lover lover = new Lover("小龙女", 18, '女'); Person person = new Person("杨过", 17, '男', lover); // person只有实现了Cloneable接口,才可以调用clone() Person personCopy = (Person) person.clone(); System.out.println(personCopy); System.out.println(person); //Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]] //Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]] // 修改基本数据类型和String类型的数据 personCopy.setName("神雕大侠"); personCopy.setAge(36); personCopy.setSex('M'); // 修改内部对象的数据 personCopy.getLover().setName("神仙姐姐"); personCopy.getLover().setAge(37); personCopy.getLover().setSex('F'); // 复制品的改变 完全不影响 原来对象 System.out.println(personCopy); System.out.println(person); //Person [name=神雕大侠, age=36, sex=M, lover=Lover [name=神仙姐姐, age=37, sex=F]] //Person [name=杨过, age=17, sex=男, lover=Lover [name=小龙女, age=18, sex=女]] } }