一 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;
}
@Override
public 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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", m=" + m +
'}';
}
@Override
protected 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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", m=" + m +
'}';
}
@Override
protected 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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", m=" + m +
'}';
}
@Override
protected 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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", m=" + m +
'}';
}
@Override
protected 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;
@Override
protected 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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", m=" + m +
'}';
}
@Override
protected 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()
默认执行浅拷贝,若需要深拷贝,需要手动处理。
希望能对大家有所帮助!!!