对象copy的两种方式--序列化--clone

对象实现copy有多中方式,最土的方法就是直接new,然后塞值,不过这种方法是真的low,下面着重说说Object类中的clone() 和 序列化反序列化copy

 

Object 中 clone的方法

1.Object中clone 方法是protected,虽然所有类都继承自object 但是在不同包下调用还是不被允许的,因此要重写clone方法。

2.调用clone方法clone对象时要求对象实现Cloneable接口,否则会抛出 CloneNotSupportedException

  /** @return     a clone of this instance.
     * @throws  CloneNotSupportedException  if the object's class does not
     *               support the {@code Cloneable} interface. Subclasses
     *               that override the {@code clone} method can also
     *               throw this exception to indicate that an instance cannot
     *               be cloned.
     * @see java.lang.Cloneable
     */
    protected native Object clone() throws CloneNotSupportedException;

clone 方法可以实现对象的浅copy ,什么是浅copy 举个例子

人 有 头 和 名字 两个属性 , 头 又有 头发 属性 ,现在使用clone方法 克隆一个人,则clone出来的人和原有的人是两个对象,但是发现两个人的头在内存中只有一个,也就是说,clone出来的人使用了原有人的头对象。如果改了其中一个对象头对象的属性,另一个也会跟着变。

序列化和反序列化,将对象读到内存中,在从内存中读取出来 

需要对象实现 Serializable 接口

直接上代码了,自己跑即可:

import lombok.extern.slf4j.Slf4j;

import java.io.*;

/**
 * @ClassName CommonUtils
 * @Description <工具类></>
 * @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt
 * @Date 2018/12/4 11:39
 * @Version 1.0
 */
@Slf4j
public class CommonUtils {

    /**
     * @return T
     * @Description <深度克隆对象,对象需要序列化>
     * @Author Zhaiyt
     * @Date 14:11 2018/12/4
     * @Param [obj]
     **/
    public static <T extends Serializable> T clone(T obj) {
        try {
            //将对象读取到内存中
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            ObjectOutputStream outputStream = new ObjectOutputStream(byteArrayOutputStream);
            outputStream.writeObject(obj);
            //从内存中读取
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
            ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
            return (T) objectInputStream.readObject();
        } catch (IOException e) {
            log.error("clone Object IOException");
        } catch (ClassNotFoundException e) {
            log.error("clone Object ClassNotFoundException");
        }
        return null;
    }

    public static void main(String[] args) {
        Person p = new Person();
        p.setName("zhangsan");
        p.setSix("男");
        Head h = new Head();
        h.setHair("black");
        p.setHead(h);
        Person cloneP = clone(p);
        System.out.println("深copy对象的属性 p.head 和 cloneP.head 是否相等");
        System.out.println(p.getHead().equals(cloneP.getHead()));

        //浅copy
        Person clone;
        try {
            clone = (Person) p.clone();
            System.out.println("浅copy对象的属性 p.head 和 clone.head");
            System.out.println(p.getHead().equals(clone.getHead()));
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

/**
 * @ClassName <Person>
 * @Description <人对象>
 * @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt
 * @Date 2018/12/4 16:12
 * @Version 1.0
 */
class Person implements Serializable, Cloneable {
    private String name;

    private String six;

    private Head head;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSix() {
        return six;
    }

    public void setSix(String six) {
        this.six = six;
    }

    public Head getHead() {
        return head;
    }

    public void setHead(Head head) {
        this.head = head;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", six='" + six + '\'' +
                ", head=" + head +
                '}';
    }
}

/**
 * @ClassName <Head>
 * @Description <人的属性>
 * @Author Zhai XiaoTao https://www.cnblogs.com/zhaiyt
 * @Date 2018/12/4 16:11
 * @Version 1.0
 */
class Head implements Serializable {
    private String hair;

    public String getHair() {
        return hair;
    }

    public void setHair(String hair) {
        this.hair = hair;
    }

    @Override
    public String toString() {
        return "Head{" +
                "hair='" + hair + '\'' +
                '}';
    }
}

序列化和反序列化后出来的对象发现属性对象不再是同一个对象了。

 

转载于:https://www.cnblogs.com/zhaiyt/p/10064785.html

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值