1. 什么是序列化和反序列化
序列化: 把对象转换为字节序列的过程称为对象的序列化。
反序列化: 把字节序列恢复为对象的过程称为对象的反序列化。
有时候我们想把一些信息持久化保存起来,那么序列化的意思就是把内存里面的这些对象给变成一连串 的字节描述的过程。
常见的就是变成文件。但是问题来了,我就算不序列化,也可以保存到文件当中。 有什么问题吗
2. 什么时候需要序列化
1、把内存中的对象状态保存到一个文件中或者数据库中时候;
2、 用套接字在网络上传送对象的时候
3.实现序列化的方式
一定要牢记实现序列化本身是跟语言无关的:
列举出一些其他实现序列化的方式(参考):
0、Java对象序列化
1、JSON序列化
2、XML
3、Protostuff
4、Hession(它基于HTTP协议传输,使用Hessian二进制序列化,对于数据包比较大的情况比较 友好。)
5、Dubbo Serialization(阿里dubbo序列化)
6、FST(高性能、序列化速度大概是JDK的4-10倍,大小是JDK大小的1/3左右)
7、自定义协议进行序列化
4.如何实现序列化(Java对象序列化)
自己实现一个Person类,在类当中定义成员变量 name , age , sex , stuId , count ,如果要讲Person进行序列化需要实现Serializable接口即可 。
import java.io.Serializable
class Person implements Serializable{
//private static final long serialVersionUID = 1L;
private String name;
private int age;
private String sex;
//transient修饰的变量,不能被序列化
transient private int stuId;
//static修饰的变量,不能被序列化
private static int count = 99;
public String getName() {
return name;
}
public int getAge() {
return age;
}
public String getSex() {
return sex;
}
public int getStuId() {
return stuId;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setStuId(int stuId) {
this.stuId = stuId;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", stuId=" + stuId +
",count=" + count +
'}';
}
}
序列化反序列化测试:
public class TestDemo3 {
public static void main(String[] args) throws Exception {
serializePerson();
Person person = deserializePerson();
System.out.println(person.toString());
}
/** * 序列化 */
private static void serializePerson() throws IOException {
Person person = new Person();
person.setName("agao");
person.setAge(10);
person.setSex("男");
person.setStuId(100);
// ObjectOutputStream 对象输出流,将 person 对象存储到E盘的
// person.txt 文件中,完成对 person 对象的序列化操作
ObjectOutputStream oos = new ObjectOutputStream (new FileOutputStream(new File("e:/person.txt")));
oos.writeObject(person);
System.out.println("person 对象序列化成功!");
oos.close();
}
/** * 反序列化 */
private static Person deserializePerson() throws Exception {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("e:/person.txt")));
Person person = (Person) ois.readObject();
System.out.println("person 对象反序列化成功!");
return person;
}
}
相关流的说明:
ObjectOutputStream 代表对象输出流: 它的 writeObject(Object obj) 方法可对参数指定的 obj 对象进行序列化,把得到的字节序列写到一个目标输出流中。 ObjectInputStream 代表对象输入流: 它的 readObject() 方法从一个源输入流中读取字节序列,再把它们反序列化为一个对象,并将其返 回。
结果展示:
person 对象序列化成功!
person 对象反序列化成功!
Person{name=‘bit’, age=10, sex=‘男’, stuId=0, count=99}
结果分析:
1,他实现了对象的序列化和反序列化。
2,transient 修饰的属性,是不会被序列化的 。我们的 stuId 本应是100,可现在为0.注意:内置类型 为对应0值。引用类型为null;
3、静态变量 好像也被序列化了,但是其实并没有。
5. 关于静态数据属性是否被序列化的测试
其他代码不变,主函数调用改为如下形式,并且将类中的count变量值改为888:
public static void main(String[] args) throws Exception {
//serializePerson();
Person person = deserializePerson();
System.out.println(person.toString());
}
运行结果展示:
person 对象反序列化成功! Person{name=‘bit’, age=10, sex=‘男’, stuId=0,count=888}
我们可以看到:count的值为888.
因为我们现在的情况是:
1、没有再进行序列化,直接进行反序列化
2、只是改变类中的count变量的值
如果是静态变量参与序列化,那么这个值不应该是888.应该还是上一次序列化的结果99.
结论:
静态变量的值是不会被进行序列化的。
6.关于serialVersionUID的问题
将上述代码再执行一遍运行(序列化和反序列化均要执行),接着将Person类中的 private static final long serialVersionUID = 1L;注释取消,然后屏蔽掉序列化的方法: serializePerson() ,运行主函数。
目的:当我们在类中没有指定 serialVersionUID 的时候,编译器会自动赋值,如果序列化是以默认 的 serialVersionUID ,那么反序列化也是会以那个默认的。而我们现在的情况是,以默认的 serialVersionUID 进行序列化,以自己赋值的 serialVersionUID 进行反序列化,这样代码就会出问 题。
代码示例:
public static void main(String[] args) throws Exception {
//serializePerson();
Person person = deserializePerson();
System.out.println(person.toString());
}
结果展示:
Exception in thread “main” java.io.InvalidClassException: Person;
local class incompatible: stream classdesc serialVersionUID = -5
注意这个异常: java.io.InvalidClassException
7.总结
1、一个类如果想被序列化,那么需要实现一个Serializable接口。
2、类中的静态变量的值是不会被进行序列化的,transient 修饰的属性,是不会被序列化的,内置类型 为对应0值。引用类型为null;
3、在实现这个Serializable 接口的时候,一定要给这个 serialVersionUID 赋值,最好设置为1L,这 个L最好大写来区分,不然小写看起来像是1,不同的 serialVersionUID 的值,会影响到反序列化 .
转载:https://blog.csdn.net/qq_45691220/article/details/106954049