论坛首页 Java企业应用论坛

Java克隆,Object#clone()

浏览 2456 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2014-02-20  
在Java中要实现克隆很简单,只要在需要克隆的类实现Cloneable,并调用其clone方法即可。最简单的克隆如下
<pre name="code" class="java">
package cn.quinn.test;

public class TEST implements Cloneable {
public String id;
public T2 t2;
public static void main(String[] args) {
TEST t = new TEST();
t.id = "1";
try {
TEST t2 = (TEST) t.clone();
System.out.println(t);
System.out.println(t2);
System.out.println(t2.id);
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}

}

</pre>
打印结果为
cn.quinn.test.TEST@1fb8ee3
cn.quinn.test.TEST@61de33
1
可以看到t和t2已经不是一个对象,但是id值相同。

Java中的克隆分为浅克隆和深克隆
默认的克隆方法提供的为浅克隆,浅克隆表现方式如下

<pre name="code" class="java">
package cn.quinn.test;

public class TEST implements Cloneable {

public String id;

public T2 t2;

public static void main(String[] args) {
TEST t = new TEST();
T2 t21 = new T2(); //new一个属性对象
t.t2 = t21;//把T2的对象传给t
System.out.println(t21); //打印一下
try {
TEST t2 = (TEST) t.clone();
System.out.println(t.t2); //克隆结果
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}

}

</pre>
打印结果
cn.quinn.test.T2@61de33
cn.quinn.test.T2@61de33

两个对象完全相同,这就是浅copy,当更改克隆后的对象属性的值后会影响到克隆前的对象,因为它们是同一块内存地址。

在Java中如何实现深度克隆呢?

方法很多 可以重写属性类的clone方法 ,这样做不好的地方就是一旦对象属性过多就会写很多
最好的方法就是序列化和反序列化,不过所有的类和属性类都必须实现Serializable接口
如下
<pre name="code" class="java">
package cn.quinn.test;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;

public class TEST implements Cloneable, Serializable {

public String id;

public T2 t2;

@Override
protected Object clone() throws CloneNotSupportedException {
ByteArrayOutputStream byteout = null;
ObjectOutputStream out = null;
ByteArrayInputStream bytein = null;
ObjectInputStream in = null;
try {
byteout = new ByteArrayOutputStream();
out = new ObjectOutputStream(byteout);
out.writeObject(this);

bytein = new ByteArrayInputStream(byteout.toByteArray());

in = new ObjectInputStream(bytein);

return in.readObject();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (in != null) {
in.close();
in = null;
}
} catch (Exception e) {
}
try {
if (bytein != null) {
bytein.close();
bytein = null;
}
} catch (Exception e) {
}
try {
if (out != null) {
out.close();
out = null;
}
} catch (Exception e) {
}
try {
if (byteout != null) {
byteout.close();
byteout = null;
}
} catch (Exception e) {
}
}
return null;

}

public static void main(String[] args) {
TEST t = new TEST();
T2 t21 = new T2(); //new一个属性对象
t.t2 = t21;//把T2的对象传给t
System.out.println(t21); //打印一下
try {
TEST t2 = (TEST) t.clone();
System.out.println(t2.t2); //克隆结果
} catch (CloneNotSupportedException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}

}

</pre>

<pre name="code" class="java">
package cn.quinn.test;

import java.io.Serializable;

public class T2 implements Serializable{

private String t2;

public String getT2() {
return t2;
}

public void setT2(String t2) {
this.t2 = t2;
}

}

</pre>
   发表时间:2014-02-26  
楼主玩三国杀多久了?
0 请登录后投票
   发表时间:2014-02-27  
这么简单的话题为什么还能放上来
0 请登录后投票
   发表时间:2014-02-27  
浅克隆的结果就是当前对象的基本类型的属性克隆了,但当前对象的引用类型属性仍然指向同一个引用。曾经深受其害啊
0 请登录后投票
   发表时间:2014-03-20  
jiq408694711 写道
这么简单的话题为什么还能放上来

总对人有帮助呗
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics