摘自: http://lovelace.iteye.com/blog/182772
由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象。比如函数参数类型是自定义的类时,此时便是引用传递而不是值传递。
首先要实现Cloneable接口,然后在重载clone方法,最后在clone()方法中调用了super.clone(),这也意味着无论clone类的继承结构是什么样的,super.clone()直接或间接调用了java.lang.Object类的clone()方法。
public class A implements Cloneable {
public String name;
public Object clone() {
A o = null;
try {
o = (A) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
当Class A成员变量类型是java的基本类型时(外加String类型),只要实现如上简单的clone(称影子clone)就可以。但是如果Class A成员变量是数组或复杂类型时,就必须实现深度clone。
public class A implements Cloneable {
public String name[];
public A(){
name=new String[2];
}
public Object clone() {
A o = null;
try {
o = (A) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
测试代码
- A a1=new A();
-
A a2=new A();
-
a1.name[0]="a";
-
a1.name[1]="1";
- a2=(A)a1.clone();
-
a2.name[0]="b";
-
a2.name[1]="1";
-
System.out.println("a1.name="+a1.name);
-
System.out.println("a1.name="+a1.name[0]+a1.name[1]);
-
System.out.println("a2.name="+a2.name);
-
System.out.println("a2.name="+a2.name[0]+a2.name[1]);
A a1=new A();
A a2=new A();
a1.name[0]="a";
a1.name[1]="1";
a2=(A)a1.clone();
a2.name[0]="b";
a2.name[1]="1";
System.out.println("a1.name="+a1.name);
System.out.println("a1.name="+a1.name[0]+a1.name[1]);
System.out.println("a2.name="+a2.name);
System.out.println("a2.name="+a2.name[0]+a2.name[1]);
输出结果:
- a1.name=[Ljava.lang.String;@757aef
- a1.name=b1
-
a2.name=[Ljava.lang.String;@757aef
- a2.name=b1
a1.name=[Ljava.lang.String;@757aef
a1.name=b1
a2.name=[Ljava.lang.String;@757aef
a2.name=b1
看到了吧,a1.name,a2.name的hash值都是@757aef,也就是说影子clone对name数组只是clone他们的地址!解决该办法是进行深度clone。
public Object clone() {
A o = null;
try {
o = (A) super.clone();
o.name=(String[])name.clone();//其实也很简单^_^
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
- a1.name=[Ljava.lang.String;@757aef
- a1.name=a1
-
a2.name=[Ljava.lang.String;@d9f9c3
- a2.name=b1
a1.name=[Ljava.lang.String;@757aef
a1.name=a1
a2.name=[Ljava.lang.String;@d9f9c3
a2.name=b1
需要注意的是Class A存在更为复杂的成员变量时,如Vector等存储对象地址的容器时,就必须clone彻底。
public class A implements Cloneable {
public String name[];
public Vector<B> claB;
public A(){
name=new String[2];
claB=new Vector<B>();
}
public Object clone() {
A o = null;
try {
o = (A) super.clone();
o.name==(String[])name.clone();//深度clone
o.claB=new Vector<B>();//将clone进行到底
for(int i=0;i<claB.size();i++){
B temp=(B)claB.get(i).clone();//当然Class B也要实现相应clone方法
o.claB.add(temp);
}
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return o;
}
}
分享到:
相关推荐
用 Java 语言编写的 初学者可学习的clone()
Java Clone(类的复制)实例代码 Java Clone(类的复制)实例代码
详细的描述了Java中 clone方法使用
Clone 属性的相关内容 Clone 属性的相关内容
今天小编就为大家分享一篇关于Java Clone深拷贝与浅拷贝的两种实现方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
主要介绍了 Java clone方法详解及简单实例的相关资料,需要的朋友可以参考下
java中clone的详细用法,分浅拷贝和深拷贝,并分别有详细的实例介绍。从原理分析。
Java中的clone方法详解_动力节点Java学院,动力节点口口相传的Java黄埔军校
Java中的克隆(Clone)机制,很少涉及的内容。
NULL 博文链接:https://gaoquanyang.iteye.com/blog/1177183
Java深浅clone测试代码 流拷贝 Cloneable
clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象。下面通过本文给大家介绍java中的clone方法,感兴趣的朋友一起看看吧
主要介绍了java 中clone()的使用方法的相关资料,希望通过本文能帮助大家能掌握clone()的克隆方法,需要的朋友可以参考下
java中仅有的创建对象的两种方式:①.使用new操作符创建对象;②....下面这篇文章主要通过JVM角度给大家详细谈谈Java的clone操作的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
clone的用法 希望有帮助,仅供参考 通过例子的分析,可以对克隆的方法有所深入了解
java code clone
并且由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象。比如函数参数类型是自定义的类时,此时便是引用传递而不是值传递。以下是一个小例子: ...
java中clone的详细用法,分浅拷贝和深拷贝,并分别有详细的实例介绍。从原理分析。