浅克隆:需要类实现Cloneable,并重写clone()方法
一般在重写clone()方法时,将返回值类型强转为自己类,避免每次克隆之后需要强转
public class Test {
public static void main(String[] args) throws CloneNotSupportedException {
A a1=new A();
A a2 = a1.clone();
//克隆之后 a1和a2是两个不同对象 内容相同
System.out.println(a1==a2);//false
System.out.println(a1);//A{a=1, b=2, c='3', d=D{name='1'}, e='4'}
System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='1'}, e='4'}
System.out.println("--------------------------------------");
//浅克隆之后,对String类型和8种基本类型(包装类)的改变不会影响另外一个对象的属性内容
a1.setA(5);
a1.setB(6);
a1.setC("7");
a1.setE("8");
System.out.println(a1);//A{a=5, b=6, c='7', d=D{name='1'}, e='8'}
System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='1'}, e='4'}
System.out.println("--------------------------------------");
//但是浅克隆对自定义类型的成员变量的改变,会影响另外一个对象 说明自定义对象在a1和a2中的引用地址指向了同一个对象
a1.getD().setName("改了");
System.out.println(a1);//A{a=5, b=6, c='7', d=D{name='改了'}, e='8'}
System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='改了'}, e='4'}
a2.getD().setName("又改了");
System.out.println(a1);//A{a=5, b=6, c='7', d=D{name='又改了'}, e='8'}
System.out.println(a2);//A{a=1, b=2, c='3', d=D{name='又改了'}, e='4'}
}
}
class A implements Cloneable{
int a=1;
Integer b=2;
String c=new String("3");
D d=new D();
String e="4";
@Override
public String toString() {
return "A{" +
"a=" + a +
", b=" + b +
", c='" + c + '\'' +
", d=" + d +
", e='" + e + '\'' +
'}';
}
public D getD() {
return d;
}
public void setD(D d) {
this.d = d;
}
public String getE() {
return e;
}
public void setE(String e) {
this.e = e;
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public Integer getB() {
return b;
}
public void setB(Integer b) {
this.b = b;
}
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
@Override
protected A clone() throws CloneNotSupportedException {
return (A)super.clone();
}
}
class D{
String name="1";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "D{" +
"name='" + name + '\'' +
'}';
}
}
画张图表示
下面是深克隆的一种写法
让自定义类也实现克隆,并重写clone方法
然后在对象类的克隆方法改写成下面
这样再运行上面代码, D就是不同的对象了,克隆之后,无论谁改变d的属性,都只影响自己
以集成工具默认重写equals和hashcode不影响执行结果
深克隆还有其他写法