IBM中国研发中心面试题,如何用Java写一个程序达到对象深浅克隆的效果?不能用API

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
    {
    /
    *

    • 模拟对象深/浅克隆效果
    • @author JohnGao
    • @param T: 目标克隆对象
    • @throws Exception
    • @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框架,道理是一样的。