IBM中国研发中心面试题,如何用Java写一个程序达到对象深浅克隆的效果?不能用API。来吧,大家发表意见,全分奉上。
[code="java"]
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
@author JohnGao
/
public class CloneTest
{
/*
@return T: 克隆对象
/
public static T clone(T t) throws Exception
{
/ 实例化字节数组节点流 */
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
ObjectOutputStream objectOutputStream = new ObjectOutputStream(
byteArrayOutputStream);
/* 将目标克隆对象转换成数组 */
objectOutputStream.writeObject(t);
/* 返回克隆对象 */
return (T) new ObjectInputStream(new ByteArrayInputStream(
byteArrayOutputStream.toByteArray())).readObject();
}
}
[/code]
[code="java"]
public int age;
public StringBuffer str = new StringBuffer();
@Test
public void test() throws Exception
{
MyTest myTest1 = new MyTest();
MyTest myTest2 = CloneTest.clone(myTest1);
System.out.println("myTest1.hashcode: " + System.identityHashCode(myTest1));
System.out.println("myTest2.hashcode: " + System.identityHashCode(myTest2));
myTest2.age = 15;
System.out.println("myTest1.age: " + myTest1.age);
System.out.println("myTest2.age: " + myTest2.age);
myTest1.str.append("++++");
myTest2.str.append("----");
System.out.println("myTest1.str: " + myTest1.str);
System.out.println("myTest2.str: " + myTest2.str);
}
[/code]
你看下API的实现就明白了,原理就是通过字节码进行拷贝,说到底还是JAVA传参的影响,传递的实际是对象(非基本类型)的句柄。
说不能用API,没说不能和API实现的原理一样啊
浅克隆
[code="java"]
public Object clone(){
return super.clone();
}
[/code]
深克隆
[code="java"]
public Object clone(){
Employee cloned = (Employee)super.clone();
cloned.dep = (Department)this.dep.clone();
//等等子对象
return cloned;
}
[/code]
流复制(需序列化)
[code="java"]
public Object deepClone()
{
ByteArrayOutoutStream bo=new ByteArrayOutputStream();
ObjectOutputStream oo=new ObjectOutputStream(bo);
oo.writeObject(this);
ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi=new ObjectInputStream(bi);
return(oi.readObject());
}
[/code]
LZ采纳的方案是有明显局限的:被克隆的对象必须实现Serializable接口。
应付面试可能可以,但并不完美,更加完整的解决方案是自己写程序序列化对象。可以参考Hessian序列化过程。也可以参考各种Json框架,道理是一样的。