java使用serializable进行序列化与反序列化实现对象clone(克隆)

相信很多同学都使用过serializable,相信在项目中一般你的项目经理肯定和你说过记得在你的domain的类中实现serializable,不然有时会出现一些错误。但是serializable具体是做什么的呢?为什么我们要实现他?他又有什么作用呢?

serializable

人称序列化,所谓序列化即是将对象以二进制的形式保存在你所需要的介质中,让其达到永久保存的目的。
有序列化那么一定就有反序列化,不然光存不能取又有什么意义呢? 所谓反序列化即是将序列化好的二进制内容获取并转换回对象的一个过程。
光说概念同学们也许会很蒙逼,我们直接上Demo。

Demo1(永久保存对象)

需求:将User对象内容永久保存到硬盘中,随时可以取出。
实现:

1.创建User类(一定要实现Serializable,否则会报错)

import java.io.Serializable;

/**
 * Created by beyondLi on 2017/6/7.
 */

public class User implements Serializable{
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
2.进行序列化
    //序列化测试
    @Test
    public void serializableTest() throws Exception {
        //创建一个User对象,并将其赋值
        User user = new User();
        user.setName("beyondLi");
        user.setAge(23);
        //创建内容存放位置,路径以及文件请提前创建好
        File file = new File("H:\\test.txt");
        FileOutputStream fos = new FileOutputStream(file);
        //开始序列化
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        oos.writeObject(user);
        oos.flush();
        oos.close();
        fos.close();
    }

执行后会生成文件,内容如下
这里写图片描述
MMP这是什么鬼?看不懂啊。 这就是序列化后的内容,我也看不懂。但是人家计算机能读懂。

3.反序列化取值
    //反序列化测试
    @Test
    public void serializableTest2() throws Exception {
        //获取含有二进制内容的文件
        File file = new File("H:\\test.txt");
        FileInputStream fis = new FileInputStream(file);
        //开始反序列化
        ObjectInputStream ois = new ObjectInputStream(fis);
        //将反序列化的内容取出,强转成我们所需封装到的对象上
        User user = (User) ois.readObject();
        System.out.println(user);
        ois.close();
        fis.close();
    }
4.运行结果

这里写图片描述
我们会发现 我们之前序列化的对象已经被我们直接取出了。这样我们就能通过序列化对对象内容进行永久的保存了。

5.如果User对象没有实现序列化接口则会在运行时报错

这里写图片描述
很明显告诉你serializable异常

Demo2(对象克隆)

需求:使用序列化与反序列化将user对象进行克隆,并对克隆后的数据进行修改。

1.创建User
import java.io.Serializable;

/**
 * Created by beyondLi on 2017/6/7.
 */

public class User implements Serializable{
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
2.编写克隆工具类
package com.beyondli.base.utils;

import java.io.*;

/**
 * Created by beyondLi on 2017/6/8.
 * 对象clone工具类
 */
public class CloneUtils {
    private CloneUtils() {
        throw new AssertionError();
    }

    public static <T extends Serializable> T clone(T obj) throws Exception {
        //创建一块内存来存放对象内容
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bout);
        //将对象转换成二进制内容存入到开辟的内存中(序列化)
        oos.writeObject(obj);

        //读取内存块中的二进制内容
        ByteArrayInputStream bin = new ByteArrayInputStream(bout.toByteArray());
        //将二进制内容转换回对象 反序列化
        ObjectInputStream ois = new ObjectInputStream(bin);
        return (T) ois.readObject();

    }
}
3.测试类
   @Test
   public void cloneTest() throws Exception {
        User user = new User();
        user.setName("beyondLi");
        user.setAge(23);
        //使用序列化进行克隆
        User clone = CloneUtils.clone(user);
        //修改克隆对象的其中一个值
        clone.setName("zyt");
        //输出
        System.out.println(user);
        System.out.println(clone);
    }
4.运行结果

这里写图片描述

以上是对serializable一些基本概念的理解以及实际的一些应用。内容为本人自己理解,如有不足或错误,望指出。共同成长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值