最近在CS-Notes重新学习Java的知识点,看到Clone记录一下。
浅拷贝
主函数
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, CloneNotSupportedException {
Person p1=new Person();
Dog dog=new Dog("小白");
p1.setAge(12);
p1.setName("张三");
p1.setDog(dog);
Person p2=(Person) p1.clone();
p2.setAge(23);
p2.setName("李四");
p2.getDog().setName("小黑");
System.out.println("p1="+p1+" "+p1.getDog());
System.out.println("p2="+p2+" "+p2.getDog());
}
Person类
public class Person implements Cloneable{
private int age;
private String name;
private Dog dog;
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public Dog getDog() {
return dog;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public String toString(){
return "姓名:"+this.name+" 年龄:"+this.age;
}
}
Dog类
public class Dog {
String name;
Dog(String name) {
this.name = name;
}
String getName() {
return this.name;
}
void setName(String name) {
this.name = name;
}
String getObjectAddress() {
return super.toString();
}
public String toString(){
return "狗:"+name;
}
}
Person对象使用clone()时要重写。
Person类在重写时,对于引用类型的变量没有进行处理,就只是调用了Object的clone()方法。这个是浅拷贝,拷贝对象对那个引用类型的变量的值进行变化时,原对象的值也跟着变。
深拷贝
深拷贝就是在Person类的clone()中对引用类型的属性进行拷贝,Dog类重写clone()。这个引用类型的类的属性的类型如果还有自己创造的类,就还要继续拷贝。
Person类
public class Person implements Cloneable{
private int age;
private String name;
private Dog dog;
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setDog(Dog dog) {
this.dog = dog;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
public Dog getDog() {
return dog;
}
@Override
protected Object clone() throws CloneNotSupportedException {
Object object=super.clone();
Dog dog= (Dog) ((Person)object).getDog().clone();//拷贝Dog对象
((Person)object).setDog(dog);
return object;
}
public String toString(){
return "姓名:"+this.name+" 年龄:"+this.age;
}
}
Dog类
public class Dog implements Cloneable{
String name;
Dog(String name) {
this.name = name;
}
String getName() {
return this.name;
}
void setName(String name) {
this.name = name;
}
String getObjectAddress() {
return super.toString();
}
public String toString(){
return "狗:"+name;
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
clone()方法的替代方案
clone重写时需要抛出异常,实现接口,类型强制转换。所以可以用拷贝构造函数或拷贝工厂来代替clone方法的使用,具体代码可以看看下面给出的链接。