java.lang.Cloneable 接口是一个空接口,该接口用来指明一个对象是否可以进行克隆.实现了该接口的对象可以调用clone()方法来进行对象的浅克隆.
/*
* @author 黎龙飞 , 创建日期 2008-4-16
*
* Blog : http://lilongfei1030.blog.163.com
*/
package com.lang.test;
import java.util.Vector;
class Example implements Cloneable {
private Vector<String> vector = new Vector<String>();
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void add(String s) {
vector.add(s);
}
public int getSize() {
return vector.size();
}
@SuppressWarnings("finally")
public Object clone() {
Example temp = null;
try {
temp = (Example) super.clone();
// return temp;
} catch (CloneNotSupportedException e) {
System.out.println("Clone failed");
} finally {
return temp;
}
}
}
public class TestSample {
public TestSample() {
}
public static void main(String[] args) {
Example oldExample = new Example();
oldExample.setName("old");
oldExample.add("old");
Example newExample = (Example) oldExample.clone();
newExample.setName("new");
newExample.add("new");
System.out.println("oldExample's name is:" + oldExample.getName());
System.out.println("newExample's name is:" + newExample.getName());
System.out.println("oldExample's size is:" + oldExample.getSize());
System.out.println("newExample's size is:" + newExample.getSize());
}
}
/**
oldExample's name is:old
newExample's name is:new
oldExample's size is:2
newExample's size is:2
*/
java默认的克隆是浅克隆,浅克隆仅仅克隆所考虑的对象,而不克隆它所引用的对象.所以对于oldExample和newException,其所引用的Vector对象为一个;
下面是一个使用深克隆的类:
* @author 黎龙飞 , 创建日期 2008-4-16
*
* Blog : http://lilongfei1030.blog.163.com
*/
package com.lang.test;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Vector;
class DeepClone implements Cloneable, Serializable {
private static final long serialVersionUID = -7118913611910178839L;
private Vector<String> vector = new Vector<String>();
private String name;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void add(String s) {
vector.add(s);
}
public int getSize() {
return vector.size();
}
public Object clone() {
try {
ByteArrayOutputStream b = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(b);
out.writeObject(this); //writeObject 方法用于将对象写入流中。必须使用与写入对象时相同的类型和顺序从相应 ObjectInputstream 中读回对象。
ByteArrayInputStream bIn = new ByteArrayInputStream(b.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bIn);
return (oi.readObject());
} catch (Exception e) {
return null;
}
}
}
public class TestDeepClone {
public static void main(String[] args) {
DeepClone oldExample = new DeepClone();
oldExample.setName("old");
oldExample.add("old");
DeepClone newExample = (DeepClone) oldExample.clone();
newExample.setName("new");
newExample.add("new");
System.out.println("oldExample's name is:" + oldExample.getName());
System.out.println("oldExample's size is:" + oldExample.getSize());
System.out.println("newExample's name is:" + newExample.getName());
System.out.println("newExample's size is:" + newExample.getSize());
}
}
/*
oldExample's name is:old
oldExample's size is:1
newExample's name is:new
newExample's size is:2
*/
在这种实现中,通过对象序列化方式,深克隆把要复制对象都复制了一遍.其中关于ObjectOutputStream 与ObjectInputStream 的使用可参考Java API