Java序列化与反序列化、深克隆的补充(新手必看,简单易懂)

 JAVA中是通过对象流来实现对象的序列化跟反序列化的,对象流也是一种包装流。

 

一、什么是序列化和反序列化 

        Serialization(序列化):将java对象以一连串的字节保存在磁盘文件中的过程,也可以说是保存java对象状态的过程。序列化可以将数据永久保存在磁盘上(通常保存在文件中)。Java序列化就是指把Java对象转换为字节序列的过程

        deserialization(反序列化):将保存在磁盘文件中的java字节码重新转换成java对象称为反序列化。Java反序列化就是指把字节序列恢复为Java对象的过程。


二、序列化和反序列化的优点

  • 实现了数据的持久化,通过序列化可以把数据持久地保存在硬盘上(磁盘文件)。
  • 利用序列化实现远程通信,在网络上传输字节序列。

序列化的实现:(对象——>文件)

         定义一个User类(注意:实体类必须实现Serializable接口,否则将会报一下错误)

Exception in thread "main" java.io.NotSerializableException: com.bailiban.demo5.User

public class User implements Serializable{

    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

         序列化:因为对象流也是一种包装流,所以也依赖于一个普通流

public static void main(String[] args) throws IOException {
        //序列化
        FileOutputStream outputStream = new FileOutputStream("D:\\io\\temp.abcdef");
        //对象输出流
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(outputStream);

        User user = new User("张三", 20);

        //将Java中的对象写到硬盘
        objectOutputStream.writeObject(user);
}

 反序列化的实现:(文件——>对象)

        也是先构建普通流,在构建包装流,在读取对象内容

public static void main(String[] args) throws IOException, ClassNotFoundException {
        //普通流
        FileInputStream fileInputStream = new FileInputStream("D:\\io\\temp.abcdef");
        //包装流
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

        User user = (User) objectInputStream.readObject();

        System.out.println(user);
}

---------------------------------------------------这是一条分割线---------------------------------------------------------

 之前学习Object类的clone方法的时候,提到过深克隆与浅克隆

对克隆不太了解的,可以去看看我之前的这篇博客:

深克隆与浅克隆的区别(浅显易懂)

深克隆如何实现: 通过对象流的反序列化

        User类

public class User implements Serializable,Cloneable{

    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public User(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
    public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {
        User user1 = new User("王五", 18);

        //user2:浅克隆对象
        User user2 = (User) user1.clone();

//        System.out.println(user1.getName() == user2.getName());

        //深克隆实现
        //1、序列化(将user1对象写出,写出到内存的byte数组里面) 内存——>内存
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
        objectOutputStream.writeObject(user1);

        //反序列化
        ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
        ObjectInputStream objectInputStream = new ObjectInputStream(in);
        //user3:深克隆对象
        User user3 = (User) objectInputStream.readObject();

        System.out.println(user1 == user3);                     //false
        System.out.println(user1.getName() == user3.getName()); //false 
    }

通过反序列化得到user3对象,因为深克隆会完全克隆出一份新的对象,即使引用类型属性,也会重新克隆。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值