一 Clonable 接口
在 Java SE 中,Cloneable
是一个标记接口(Marker Interface),它位于 java.lang
包中。这个接口的主要目的是标识实现该接口的类能够被合法地克隆(即可以调用 Object
类中的 clone()
方法)。
1.当我们点入Clonable 接口的源代码中,可以发现里面什么都没有。
因为Cloneable
是一个标记接口,用来表明类的对象可以被克隆。
2.如果不实现 Cloneable
接口而直接调用 clone()
方法,系统将抛CloneNotSupportedException
异常。
3.Clonable 接口的实现
第一步
class Money{public double money=9.9;
}
public class Person {public String name;public int age;public Money m=new Money();public Person(String name,int age){this.name=name;this.age=age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", m=" + m +'}';}
}
public class Test {public static void main(String[] args) {Person person1=new Person("wang",10);Person person2=person1.}}
问题:但是我们发现 ,在person1的引用中没有发现clone()
第二步
实现Cloneable接口,并重写Object接口的克隆方法
class Money{public double money=9.9;}
public class Person implements Comparable{public String name;public int age;public Money m=new Money();public Person(String name,int age){this.name=name;this.age=age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", m=" + m +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class Test {public static void main(String[] args) {Person person1=new Person("wang",10);Person person2=person1.clone();}}
问题:但我们发现,代码依旧报错。
第三步
由于clone()方法返回值是Object是父类,所以要将克隆方法强转为子类。
class Money{public double money=9.9;
}
public class Person implements Comparable{public String name;public int age;public Money m=new Money();public Person(String name,int age){this.name=name;this.age=age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", m=" + m +'}';}@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class Test {public static void main(String[] args) {Person person1=new Person("wang",10);Person person2=(Person) person1.clone();}}
问题:但是代码依旧报错
第四步
因为有异常,所以得先处理
class Money{public double money=9.9;
}
public class Person implements Comparable{public String name;public int age;public Money m=new Money();public Person(String name,int age){this.name=name;this.age=age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", m=" + m +'}';}@Overrideprotected Object clone()throws CloneNotSupportedException {return super.clone();}
}
public class Test {public static void main(String[] args) throws CloneNotSupportedException{Person person1=new Person("wang",10);Person person2=(Person) person1.clone();}}
最终运行成功
过程如下
二 拷贝
1.浅拷贝
class Money{public double money=9.9;
}
public class Person implements Cloneable{public String name;public int age;public Money m=new Money();public Person(String name,int age){this.name=name;this.age=age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", m=" + m +'}';}@Overrideprotected Object clone()throws CloneNotSupportedException {return super.clone();}
}
public class Test {public static void main(String[] args)throws CloneNotSupportedException{Person person1=new Person("wang",10);Person person2=(Person) person1.clone();
/* System.out.println(person1);System.out.println(person2);*/System.out.println("修改前"+person1.m.money);System.out.println("修改前"+person2.m.money);person1.m.money=100;System.out.println("修改后"+person1.m.money);System.out.println("修改后"+person2.m.money);}}
我们可以看出,只克隆了Person对象,没有克隆Money对象 ,这种现象就叫做浅拷贝。
2.深拷贝
如何让Money也进行克隆呢?
接下来就是深拷贝过程
class Money implements Cloneable{public double money=9.9;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}
public class Person implements Cloneable{public String name;public int age;public Money m=new Money();public Person(String name,int age){this.name=name;this.age=age;}@Overridepublic String toString() {return "Person{" +"name='" + name + '\'' +", age=" + age +", m=" + m +'}';}@Overrideprotected Object clone()throws CloneNotSupportedException {//return super.clone();Person tem=(Person) super.clone();tem.m=(Money) this.m.clone();return tem;}
}
public class Test {public static void main(String[] args)throws CloneNotSupportedException{Person person1=new Person("wang",10);Person person2=(Person) person1.clone();
/* System.out.println(person1);System.out.println(person2);*/System.out.println("修改前"+person1.m.money);System.out.println("修改前"+person2.m.money);person2.m.money=100;System.out.println("修改后"+person1.m.money);System.out.println("修改后"+person2.m.money);}}
过程如下:
注:clone()
默认执行浅拷贝,若需要深拷贝,需要手动处理。
希望能对大家有所帮助!!!