Hello~小伙伴们!本篇学习Clonable接口与深拷贝,一起往下看吧~(画图水平有限,两张图,,我真的画了巨久,求路过的朋友来个3连~阿阿阿~~~)
目录
1、Clonable接口概念
2、拷贝
2、1浅拷贝
2、2深拷贝
1、Clonable接口概念
Java 中内置了一些很有用的接口, Clonable 就是其中之一。
祖先类Object 中存在一个 clone 方法, 调用这个方法可以创建一个对象的 "拷贝". 但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出 CloneNotSupportedException 异常。
那么具体如何使用Clonable接口呢?
以拷贝为为例来实现Clonable接口吧
2、拷贝
拷贝分为深拷贝和浅拷贝,就是从不同深度上去拷贝一个东西。接下来以拷贝person为例实现代码。注意:拷贝后的东西会占用新内存,也就是两者指向不同空间,互不影响。(该条件是区分是否被拷贝的核心!!!)
2、1浅拷贝
1、先创建Person类与Money类,并实例化两者对象。(以Money类对象是否拷贝来区别深拷贝或浅拷贝)
//Money类 public class Money { public double qianqian=9.9; @Override public String toString() { return "Money{" + "qianqian=" + qianqian + '}'; } }//Person类
public class Person{ String name; int age; public Person(String name, int age) { this.name = name; this.age = age; } //在Pweson类中实例化Money Money money = new Money(); @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
2、在测试类中调用Clone方法
调用Clone方法不是那么的随意简单,需要注意四个点
(1)、在需要拷贝的类中重写Object类中的clone方法.
@Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }
(2)、将被拷贝的对象强转为该对象所属类。
从上面的代码块可以看到 clone 方法的返回类型为Obeject,所以要强转为拷贝对象所属类。
Person person2 =(Person) person1.clone();
(3)、 异常处理。在main方法体前添加throws CloneNotSupportedException。如下
public class Test { public static void main(String[] args) throws CloneNotSupportedException { Person person1 = new Person("zhangsan", 21); Person person2 = (Person) person1.clone(); } }
(4)实现接口,表示此类可被拷贝。
public class Person implements Cloneable {....}
3、通过person2.money来改变该money的属性的值。
person2.money.qianqian=99.99;
代码结果如图:
从结果可以看出,这种克隆方式是浅拷贝,怎么理解呢?
看图,改变person2.money来改变属性qianqian的值,也影响了person1.money的属性值。说明只只拷贝了Person类,没有拷贝Money类。这样的拷贝方式成为浅拷贝。
那么如何也将Money拷贝呢?
2、2深拷贝
拷贝Money只需要在浅拷贝的基础上修改两个地方。
1、在Money类中重写Object类中的clone方法
@Override protected Object clone() throws CloneNotSupportedException { return super.clone(); }
2、在Person类中重写Object类中的clone方法
@Override protected Object clone () throws CloneNotSupportedException { Person person2 = (Person) super.clone(); person2.money = (Money) this.money.clone(); return person2; }
这里分了两部拷贝,第一步,先拷贝Person。第二步,拷贝Money(this.表当前调用clone方法的对象即person1)
整体代码如下:
//Money类
public class Money implements Cloneable{
public double qianqian=9.9;
@Override
public String toString() {
return "Money{" +
"qianqian=" + qianqian +
'}';
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
//Person类
public class Person implements Cloneable {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
Money money = new Money();
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
protected Object clone () throws CloneNotSupportedException {
Person person2 = (Person) super.clone();
person2.money = (Money) this.money.clone();
return person2;
}
}
//测试类
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person("zhangsan", 21);
Person person2 = (Person) person1.clone();
System.out.println(person1+"有"+person1.money);
System.out.println(person2+"有"+person2.money);
person2.money.qianqian=99.99;
System.out.println("--------------------------------------------------------");
System.out.println(person1+"有"+person1.money);
System.out.println(person2+"有"+person2.money);
}
}
代码结果:
加图理解:
本篇类的Clonable接口和深拷贝就学习到这里,是不是收获满满呢,如果觉得文章写的不错,留下小红心再走吧。后面一篇学习做图书管理系统!关注我,不要错过哦!~