一、⭐⭐⭐什么是序列化和反序列化🌙🌙🌙
序列化:通过IO字节流的方式,将jvm内存中的Java对象转换为另外一种格式持久存储下来(记录到文件里、存储到数据库里、上传到网络,本文采用的是记录到文件里);
反序列化:通过IO字节流的方式,将被持久化的特定格式的Java对象反序列化还原出来。
二、⭐⭐⭐序列化和反序列化的使用要点🌙🌙🌙
1. 序列哈反序列化要先实现 Serializable 接口;
2. transient不参与序列化 ;
3. static修饰的属性不参与序列化(先将Java对象序列化到文件中,然后修改Java对象的static属性的值,再反序列化就可以对比得出该结论);
4. serialVersionUID 的作用:确保Java对象的版本安全或版本之间相互兼容:
⭐ 若不显示指定,则Java会自动帮我们生成一个,生成规则是根据Java对象的属性计算出来的,若属性有增删(属性值变动不会影响,非static的),则会生成不同的serialVersionUID;
⭐ 若显示指定,可以保证一个Java对象的不同版本之间,只要指定的是相同的一串serialVersionUID,则序列化和反序列化可以相互兼容。
示例代码,如下:
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
/*序列化反序列化
0 序列哈反序列化要先实现 Serializable 接口;
1 transient不参与序列化 ;
2 static修饰的属性不参与序列化(先将Java对象序列化到文件中,然后修改Java对象的static属性的值,再反序列化就可以对比得出该结论) ;
3 serialVersionUID 的作用:确保Java对象的版本安全或版本之间相互兼容
1) 若不显示指定,则Java会自动帮我们生成一个,生成规则是根据Java对象的属性计算出来的,若属性有增删(属性值变动不会影响,非static的),则会生成不同的serialVersionUID;
2) 若显示指定,可以保证一个Java对象的不同版本之间,只要指定的是相同的一串serialVersionUID,则序列化和反序列化可以相互兼容。
*/
class House implements Serializable{
private String owner;
private transient String size;
private static String price="20W";
private String test="test2";
public House(String owner, String size) {
super();
this.owner = owner;
this.size = size;
}
@Override
public String toString() {
return "House [owner=" + owner + ", size=" + size + ", price=" + price + ", test=" + test + "]";
// return "House [owner=" + owner + ", size=" + size + ", price=" + price + "]";
}
public static String getPrice() {
return price;
}
public static void setPrice(String price) {
House.price = price;
}
}
public class SerializationTest {
public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException {
//序列化Java对象到本地文件
// serialization();//serialization success:House [owner=Tom, size=100square, price=50W]
//从本地文件反序列化出Java对象
deserialization();//deserialization success:House [owner=Tom, size=null, price=20W]
}
private static void serialization() throws FileNotFoundException, IOException {
House house = new House("Tom","100square");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("D:/House.txt")));
oos.writeObject(house);//这里别忘记写了,否则会导致反序列化时读到了空文件出错
oos.close();
System.out.println("serialization success:" + house);
}
private static void deserialization() throws FileNotFoundException, IOException, ClassNotFoundException {
ObjectInputStream ois = null;House house =null;
// try{
ois = new ObjectInputStream(new FileInputStream(new File("D:/House.txt")));
house = (House)ois.readObject();
/*}catch(EOFException e){//若读取到空文件,这里会报EOFException的错
System.out.println("文件读取结束");
}
ois.close();*/
System.out.println("deserialization success:" + house);
}
}
三、⭐⭐⭐序列化和反序列化可以用来干嘛🌙🌙🌙
有了序列化和反序列化,就可以实现Java对象的传输,不仅仅像本文的示例代码演示的就在本地小打小闹玩一下,而是通过IO字节流的方式可以实现Java对象的远程传输,这样就可以扩展去做很多事情,比如两台分布式部署的Java进程间通过传输Java对象实现一些交互的处理逻辑。