1、clone();======>父类默认的拷贝方法是浅拷贝。父类中的修饰符是:protected。
浅拷贝:
Person类中,实现implements Cloneable接口
@Override
重写clone()这个父类方法后,还需要把protected改为public,
类型是当前重写的子类类型才能正常使用
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public class boy {
String name;
int age;
//get、set、有参无参构造、toString方法
}
public class Person implements Cloneable{
String name;
String sex;
int age;
boy boy;
}
public class Test2 {
public static void main(String[] args) throws CloneNotSupportedException {
Person p1 = new Person();
p1.setName("李白");
p1.setSex("女");
p1.setAge(18);
Person p2 = p1.clone();
System.out.println(p1+"===="+p1.hashCode());
System.out.println(p2+"===="+p2.hashCode());
boy b = new boy();
b.setName("小孩");
b.setAge(3);
p1.setBoy(b);
Person p3 = p1.clone();
System.out.println(p1+"========"+p1.hashCode()+"====="+p1.getBoy().hashCode());
System.out.println(p1+"========"+p3.hashCode()+"======="+p1.getBoy().hashCode());
}
}

结论:
-
- 通过测试发现克隆出来的对象虽然不一致,但是底层的成员变量的哈希值是一致的。这种复制我们称之为:浅表复制。
浅表复制的内存结构:

浅表复制的弊端
-
- 由于浅表复制导致克隆的对象中成员变量的底层哈希值一致。
- 如果我们操作其中一个对象的的某个成员变量(比如改变boy类里的name值)内容,就会导致,所有的克隆对象的成员内容(boy.name值)发生改变。
深层复制:
// Person类中,实现implements Cloneable接口
// 深表复制从写clone()方法
@Override
public Person clone() throws CloneNotSupportedException {
Person pc = (Person) super.clone();
// boy类中也要重写clone()方法
pc.setBoy(boy.clone());
return pc;
}
//boy类实现Cloneable方法
// 重写clone()方法
@Override
public boy clone() throws CloneNotSupportedException {
return (boy) super.clone();
}
public static void main(String[] args) throws CloneNotSupportedException {
Person p1 = new Person();
p1.setName("李白");
p1.setAge(12);
p1.setSex("女");
boy b = new boy();
b.setName("十三娘");
b.setAge(18);
p1.setBoy(b);
Person p2 = p1.clone();
System.out.println(p1+"======="+p1.hashCode()+"========"+p1.getBoy().hashCode());
System.out.println(p2+"======="+p2.hashCode()+"========"+p2.getBoy().hashCode());
b.setName("许七安");
p2.setBoy(b);
System.out.println(p2+"======="+p2.hashCode()+"========"+p2.getBoy().hashCode());
}
深层复制的内存结构:

结论:
使用克隆接口完成深度复制的弊端:
-
- 当Person类中存在多个类属性时
- 重复实现Cloneable接口
- 重复实现clone方法
- 重复改写Person类的clone方法
可以使用IO流的方式进行复制操作(深度复制),可以解决重复修改源代码的问题。
-
-
- Person类需要实现Cloneable和Serialization接口
- Person中的两个类属性也需要实验Serialization接口,但不用再重写clone()方法了
-

浙公网安备 33010602011771号