Clonable接口和深拷贝\浅拷贝
拷贝原理
class Person implements Cloneable{
public int age = 2;
@Override
protected Object clone() throws CloneNotSupportedException {
//要想完成克隆,必须调用Object,重写clone()方法
return super.clone();
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}
public class Test1 {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person();
Person person2 = (Person)person1.clone();//向下转型
System.out.println(person1.age);
System.out.println(person2.age);
}
运行结果:
2
2

问题:clone方法是Object的方法,所以类都是继承Object的,为什么还要重写克隆方法呢?

我们去看克隆源码发现,克隆是C++代码实现的Object类中的方法.在源代码中Object的访问修饰符是protected修饰的,所以可以得出它们不是在同一包当中.确实可以通过super访问到.但是没有重写克隆方法和传入要克隆的地址.所以代码报错
class Person implements Cloneable{
public int age = 2;
// @Override
// protected Object clone() throws CloneNotSupportedException {
// //要想完成克隆,必须调用Object,重写clone()方法
// return super.clone();
// }
@Override
public String toString() {
return "Person{" +
"age=" + age +
'}';
}
}
public class Test1 {
public void func() throws CloneNotSupportedException {
Person person1 = new Person();
Person person2 = (Person)super.clone();
System.out.println(person1);
System.out.println(person2);
}
public static void main(String[] args) throws CloneNotSupportedException {
Test1 test = new Test1();
test.func();
}
}

浅拷贝
package com.cou;
class Name implements Cloneable{
public String name = "张三";
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable{
public int age = 2;
public Name names = new Name();
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
public class Test1 {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person();
Person person2 = (Person)person1.clone();//向下转型
System.out.println("person1年龄深拷贝前" + person1.age);
System.out.println("person2年龄深拷贝前" + person2.age);
person2.age = 23;
System.out.println("person1年龄深拷贝后" +person1.age);
System.out.println("person1年龄深拷贝后" +person2.age);
System.out.println("名字是深拷贝");
System.out.println("person1名字浅拷贝前" + person1.names.name);
System.out.println("person2名字浅拷贝前" + person2.names.name);
person2.names.name = "王五";
System.out.println("person1名字浅拷贝后" + person1.names.name);
System.out.println("person2名字浅拷贝后" + person2.names.name);
}
}


深拷贝
package com.cou;
class Name implements Cloneable{
public String name = "张三";
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
class Person implements Cloneable{
public int age = 2;
public Name names = new Name();
@Override
protected Object clone() throws CloneNotSupportedException {
//深拷贝
Person tmp = (Person) super.clone();
tmp.names = (Name) this.names.clone();
return tmp;
}
}
public class Test1 {
public static void main(String[] args) throws CloneNotSupportedException {
Person person1 = new Person();
Person person2 = (Person)person1.clone();//向下转型
System.out.println("person1年龄深拷贝前" + person1.age);
System.out.println("person2年龄深拷贝前" + person2.age);
person2.age = 23;
System.out.println("person1年龄深拷贝后" +person1.age);
System.out.println("person1年龄深拷贝后" +person2.age);
System.out.println("名字是深拷贝");
System.out.println("person1名字深拷贝前" + person1.names.name);
System.out.println("person2名字深拷贝前" + person2.names.name);
person2.names.name = "王五";
System.out.println("person1名字深拷贝后" + person1.names.name);
System.out.println("person2名字深拷贝后" + person2.names.name);
}
}

总结:深拷贝和浅拷贝,不是哪个方法决定的,而是看你自己的代码来决定实现的.
本文探讨了Java中的克隆机制,包括为何需要重写`clone()`方法,以及浅拷贝和深拷贝的区别。示例代码展示了如何实现浅拷贝和深拷贝,强调了深拷贝和浅拷贝的实现取决于程序员的代码实现,而非特定的克隆方法。
566

被折叠的 条评论
为什么被折叠?



