让星星⭐月亮告诉你,如何玩转序列化 反序列化 Serializable transient serialVersionUID

24
四月
2021

一、⭐⭐⭐什么是序列化和反序列化🌙🌙🌙

序列化:通过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对象实现一些交互的处理逻辑。

TAG

网友评论

共有访客发表了评论
请登录后再发布评论,和谐社会,请文明发言,谢谢合作! 立即登录 注册会员