Java序列化可以实现将我们的对象转化为字节序列,反序列化则是将字节序列转化为我们的Java对象
为什么要有Java序列化和反序列化
我们知道,当两个进程进行远程通信时,可以相互发送各种类型的数据,包括文本、图片、音频、视频等, 而这些数据都会以二进制序列的形式在网络上传送。那么当两个Java进程进行通信时,能否实现进程间的对象传送呢?答案是可以的。如何做到呢?这就需要Java序列化与反序列化了。换句话说,一方面,发送方需要把这个Java对象转换为字节序列,然后在网络上传送;另一方面,接收方需要从字节序列中恢复出Java对象。
用到的api
ObjectOutputStream和ObjectInputStream
代码实践
Person.java
package com.ysk.serialVersion;
import java.io.Serializable;
public class Person implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1893695103711480670L;
public int id;
public String name;
public Person(int id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return "Person: " + id + " " + name;
}
}
反序列化
package com.ysk.serialVersion;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
//反序列化
public class DeserialTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
Person person;
FileInputStream fis = new FileInputStream("Person.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
person = (Person) ois.readObject();
ois.close();
System.out.println("Person Deserial" + person);
}
}
1.序列化后,为Person对象新增一个属性比如: private int age;
我们发现为默认的属性赋值了0。
2.序列化后,删除Person的一个属性,比如:id
发现只是我们的属性丢失了,并没有抛出异常
3.删除serialVersionUID ,然后进行序列化,然后增加一个属性比如: private int age;
抛出了异常
Exception in thread "main" java.io.InvalidClassException: com.ysk.serialVersion.Person; local class incompatible: stream classdesc serialVersionUID = -861214935017896986, local class serialVersionUID = -1893695103711480670
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:616)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1630)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at com.ysk.serialVersion.DeserialTest.main(DeserialTest.java:13)
Transient 关键字
为属性加上Transient 关键字,会发现我们的某一个属性没有被序列化,反序列化出来的结果也为null或者0,这就是我们这个关键字的作用。