浅克隆:需要类实现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);//falseSystem.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";@Overridepublic 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;}@Overrideprotected 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;}@Overridepublic String toString() {return "D{" +"name='" + name + '\'' +'}';}
}
画张图表示
下面是深克隆的一种写法
让自定义类也实现克隆,并重写clone方法
然后在对象类的克隆方法改写成下面
这样再运行上面代码, D就是不同的对象了,克隆之后,无论谁改变d的属性,都只影响自己
以集成工具默认重写equals和hashcode不影响执行结果
深克隆还有其他写法