文章目录
序列化和反序列化
一:概念
序列化(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
学习如逆水行舟,不进则退