clone的一知半解-Java

    Java中要实现clone必须实现Cloneable接口,并重写clone方法。但是惊奇的发现接口中居然空无一物,clone方法是在Object中就有定义的。

    像Cloneable这样的接口被称作标记接口,其意义是:以接口的形式标记对象是否拥有某种能力。这也是接口的一种作用,为某种规范而存在(个人理解,有看法可讨论)。关于标记相关,详见:http://www.cnblogs.com/xinhuaxuan/p/6349165.html

clone分 深clone浅clone

Java中Object实现的克隆为浅克隆,若对象A中有其他对象P,则若A 中的对象P发生改变时,其克隆对象A`中的P也会改变,因为其使用的引用指向同一个对象。

若想实现深克隆,需重写clone方法。可以采用序列化的方式,使用对象流实现。但被克隆对象需要实现Serializable接口

package lc.clone.deep;

import java.io.Serializable;

//要实现深克隆必须实现Serializable接口 
public class DeepClone implements Serializable
{
    private int a;
    private String b;
    private int[] c;

    public int getA()
    {
        return a;
    }

    public void setA(int a)
    {
        this.a = a;
    }

    public String getB()
    {
        return b;
    }

    public void setB(String b)
    {
        this.b = b;
    }

    public int[] getC()
    {
        return c;
    }

    public void setC(int[] c)
    {
        this.c = c;
    }

}

测试类:
package lc.clone.deep;

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

public class Test
{

    public static void main(String[] args) throws CloneNotSupportedException
    {
        Test t = new Test();
        DeepClone dc1 = new DeepClone();
        // 对dc1赋值 
        dc1.setA(100);
        dc1.setB("clone1");
        dc1.setC(new int[] { 1000 });

        System.out.println("克隆前: dc1.a=" + dc1.getA());
        System.out.println("克隆前: dc1.b=" + dc1.getB());
        System.out.println("克隆前: dc1.c[0]=" + dc1.getC()[0]);
        System.out.println("-----------");

        DeepClone dc2 = (DeepClone) t.deepClone(dc1);
        // 对c2进行修改 
        dc2.setA(50);
        dc2.setB("clone2");
        int[] a = dc2.getC();
        a[0] = 500;
        dc2.setC(a);

        System.out.println("克隆前: dc1.a=" + dc1.getA());
        System.out.println("克隆前: dc1.b=" + dc1.getB());
        System.out.println("克隆前: dc1.c[0]=" + dc1.getC()[0]);
        System.out.println("-----------");

        System.out.println("克隆后: dc2.a=" + dc2.getA());
        System.out.println("克隆后: dc2.b=" + dc2.getB());
        System.out.println("克隆后: dc2.c[0]=" + dc2.getC()[0]);

    }

    // 用序列化与反序列化实现深克隆 
    public Object deepClone(Object src)
    {
        Object o = null;
        try
        {
            if (src != null)
            {
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(baos);
                oos.writeObject(src);
                oos.close();

                ByteArrayInputStream bais = new ByteArrayInputStream(baos
                        .toByteArray());
                ObjectInputStream ois = new ObjectInputStream(bais);

                o = ois.readObject();
                ois.close();
            }

        } catch (IOException e)
        {
            e.printStackTrace();
        } catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
        return o;
    }

}

测试结果如下:
结果:
克隆前: dc1.a=100
克隆前: dc1.b=clone1
克隆前: dc1.c[0]=1000
-----------
克隆前: dc1.a=100
克隆前: dc1.b=clone1
克隆前: dc1.c[0]=1000
-----------
克隆后: dc2.a=50
克隆后: dc2.b=clone2
克隆后: dc2.c[0]=500

关于可序列化内容,日后更新学习。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值