序列化和反序列化(四)——序列化存储规则

示例1

import java.io.*;

class UserInfo implements Serializable{

	private static final long serialVersionUID = -4078405042146324828L;
}

public class Test {

	public static void main(String[] args) {
		try {
			ObjectOutput out = new ObjectOutputStream(new FileOutputStream("user_info.ser"));
			UserInfo userInfo = new UserInfo();
			//将一个对象两次写入文件
			out.writeObject(userInfo);
			out.flush();
			System.out.println(new File("user_info.ser").length());
			out.writeObject(userInfo);
			out.flush();
			System.out.println(new File("user_info.ser").length());
			out.close();

			ObjectInput in = new ObjectInputStream(new FileInputStream("user_info.ser"));
			// 判断两个引用是否为同一个对象
			System.out.println((UserInfo) in.readObject() == (UserInfo) in.readObject());
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

       描述:同一对象两次写入文件,输出每次写入后文件大小;从文件中反序列化出两个对象,比较两个对象是否为同一对象,运行结果如下:

        一般的思维是,两次写入对象,文件大小会变为两倍的大小,事实是第二次写入对象时文件只增加了 5 字节,为什么?Java 序列化机制为了节省磁盘空间,具有特定的存储规则,当写入文件的为同一对象时,并不会再将对象的内容进行存储,而只是再次存储一份引用,上面增加的 5 字节的存储空间就是新增引用和一些控制信息的空间。反序列化时,恢复引用关系,两次反序列化指向唯一的对象,故输出 true。

示例2

import java.io.*;

class UserInfo implements Serializable{
	
	public int age;
	private static final long serialVersionUID = -4078405042146324828L;
}

public class Test{

	public static void main(String[] args) {
		try {
			ObjectOutput out = new ObjectOutputStream(new FileOutputStream("user_info.ser"));
			UserInfo userInfo = new UserInfo();
			userInfo.age = 1;
			out.writeObject(userInfo);
			out.flush();
			userInfo.age = 100;
			out.writeObject(userInfo);
			out.flush();
			out.close();
			
			ObjectInput in = new ObjectInputStream(new FileInputStream("user_info.ser"));
			userInfo = (UserInfo)in.readObject();
			System.out.println(userInfo.age);
			userInfo = (UserInfo)in.readObject();
			System.out.println(userInfo.age);
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

       描述:同一个对象序列化两次,第二次序列化前修改对象属性值;从序列化文件中依次读出两个对象并输出两个对象的属性值,运行结果如下:

      为什么两个输出的都是 1?第一次写入对象以后,第二次再试图写入时,虚拟机根据引用关系已经知道有一个相同对象已经写入文件,因此第二次写入只存储一份引用,即第二次反序列化时得到的依然是第一次序列化的对象,使用一个文件多次 writeObject 需要特别注意这个问题。

发布了327 篇原创文章 · 获赞 571 · 访问量 164万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览