序列化、反序列化 这一篇足矣

序列化和反序列化

一:概念

序列化(Serialization) : Java对象转成字节序列 【持久化】

反序列化(deserialization):字节序列恢复成Java对象

在这里插入图片描述

代码实现

1.建立实体类【序列化对象】

//序列化的Java对象  对象必须实现接口 Serializable 才能进行序列化和反序列化
package entity;

import java.io.Serializable;

public class Book implements Serializable {
    private String bookName;
    private Integer bookPrice;

    //无参、有参构造器、setter、getter 均省略。。。
    
    @Override
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", bookPrice=" + bookPrice +
                '}';
    }
}

2、测试: 序列化

package Test_project;

import entity.Book;
import org.junit.jupiter.api.Test;
import java.io.*;

public class test_Serialization {
    //序列化
    @Test
    public void test() throws IOException {
        Book book = new Book("三国演义", 108);

        String txt_name = "三国演义.txt";
        File file = new File(txt_name);
        FileOutputStream fileOutputStream = new FileOutputStream(file);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

        objectOutputStream.writeObject(book);

        objectOutputStream.close();

        System.out.println("序列化成功");
    }
}

//控制台
//序列化成功

打开生成的 三国演义.txt 文件

在这里插入图片描述

图片中正是我们的Java对象序列化后生成的奇怪东西(流模式,字节序列) 存在txt文件中

3、测试:反序列化

package Test_project;

import entity.Book;
import org.junit.jupiter.api.Test;
import java.io.*;

public class test_Serialization {
    //反序列化
    @Test
    public void test1() throws IOException, ClassNotFoundException {
        File file = new File("三国演义.txt");  //这里写的是刚刚序列化生成的文件路径
        FileInputStream fileInputStream = new FileInputStream(file);
        ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);

        Book book =(Book) objectInputStream.readObject();

        System.out.println("反序列化结果:\n" + book);
    }
}

//控制台
//反序列化结果:
//Book{bookName='三国演义', bookPrice=108}

4、Tip : Serializable 接口内其实什么都没有,空的。然而如果不写的话会报错,原因是因为序列化的过程中ObjectOutputStream 的writeObject方法会对传入的对象进行类型判断,判断是不是1.字符串2.数组3.枚举4.Serializable 。如果都不是会报错

为什么需要序列化和反序列化

对于通信传输过程中的,文本,视频,音频等文件,是无法通过Java实体类对象来进行直接传输的。
所以我们需要将Java对象转换成一种格式,这种格式支持通信传输。于是序列化和反序列化就应运而生。

不需要序列化的属性?

如果在序列化的时候希望某个属性不需要序列化。与两种方案:

在实现Serialization接口的情况下
1.使用static修饰 [序列化过程只序列化对象,不序列化类]
2.使用transient属性修饰

private static String bookName;
private transient String bookName;

对于未序列化的属性,在反序列化的时候,返回为null

序列化的重要属性 serialVersionUID

对于序列化和反序列化的过程,我们需要一个唯一标识来进行标志,如果标志不一致的时候,对象在反序列化的过程中会报错

如果没有写这个属性会怎么样呢?
JVM在编译的时候会自动赋值,根据实体类的对象属性等一切信息生成一个唯一标识(类似hash值)

//写法
private static final long serialVersionUID = -123456747877L;

serialVersionUID 是自动生成好还是手动赋值好

先说结论:

可以自动赋值,但是与之对应的实体类最好不要动(增删改),否则反序列化大概率失败。
如果后续大概率改动对应实体类,请一定手动赋值这个属性。

实例验证:

自动添加 serialVersionUID

在实体类对象中增加一个bookAuthor属性

//序列化的Java对象  对象必须实现接口 Serializable 才能进行序列化和反序列化
package entity;
import java.io.Serializable;

public class Book implements Serializable {
    private String bookName;
    private Integer bookPrice;
    private String bookAuthor;

    //无参、有参构造器、setter、getter 均省略。。。
    
    @Override
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", bookPrice=" + bookPrice +
                ", bookAuthor='" + bookAuthor + '\'' +
                '}';
    }
}

然后在对原来的实体类序列化生成的文件进行反序列化

//报错信息  大意就是前后生成的 serialVersionUID 不一致(计算得出的)
java.io.InvalidClassException: entity.Book; local class incompatible: stream classdesc serialVersionUID = -2822489192967149876, local class serialVersionUID = -4826660588514736000

手动添加:serialVersionUID

第一步:删除刚刚的三国演义.txt文件

第二步:改写实体类

//序列化的Java对象  对象必须实现接口 Serializable 才能进行序列化和反序列化

package entity;

import java.io.Serializable;

public class Book implements Serializable {
    //手动添加 serialVersionUID
    private static final long serialVersionUID = -123456789L;
    
    private String bookName;
    private Integer bookPrice;

    //无参、有参构造器、setter、getter 均省略。。。

    @Override
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", bookPrice=" + bookPrice +
                '}';
    }
}

第三步:序列化重新生成 三国演义.txt文件

第四步:实体类增加字段

//序列化的Java对象  对象必须实现接口 Serializable 才能进行序列化和反序列化
package entity;
import java.io.Serializable;

public class Book implements Serializable {
    private static final long serialVersionUID = -123456789L;
    
    private String bookName;
    private Integer bookPrice;
    private String bookAuthor;

    //无参、有参构造器、setter、getter 均省略。。。
    
    @Override
    public String toString() {
        return "Book{" +
                "bookName='" + bookName + '\'' +
                ", bookPrice=" + bookPrice +
                ", bookAuthor='" + bookAuthor + '\'' +
                '}';
    }
}

第四步:反序列化

神奇的一幕发生了

在这里插入图片描述

Over

学习如逆水行舟,不进则退

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值