java序列化与反序列化进阶(二)

1、生成序列化文件

  为方便分析,Person对象进行了调整,如下:

package com.test;

import java.io.Serializable;

public class Person implements Serializable{

	private static final long serialVersionUID = 3482314192692351792L;
	private int weight;
	private int age;
	private String name;
	public Person(){
		
	}
	public int getWeight() {
		return weight;
	}
	public void setWeight(int weight) {
		this.weight = weight;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return "[weight:"+weight+",name:"+name+",age:"+age+"]";
	}
}

执行序列化操作,部分代码如下:

/**
	 * 序列化
	 * 
	 * @param filePath
	 *            序列化要写入的文件路径
	 * @throws Exception
	 */
	public static void writeObject(String filePath) throws Exception {
		Person p = new Person();
		p.setAge(18);
		p.setName("testPersonName");
		p.setWeight(120);

		ObjectOutputStream oos = null;
		try {
			oos = new ObjectOutputStream(new FileOutputStream(filePath));
			oos.writeObject(p);
			oos.flush();
		} finally {
			if (oos != null) {
				oos.close();
			}
		}
	}

2、由字节序列恢复对象

通过文本编辑器打开序列化文件(我是通过EditPlus打开,选择十六进制),如下图:

java序列化与反序列化进阶(二)_第1张图片

对上图的数据进行分析:

第一部分,固定信息:

·0xAC 0xED代表头部信息,固定;

·0X00 0X05表示序列化的版本;

第二部分:类的描述信息

·0x73 表示新对象,可以查看ObjectStreamConstants;

·0x72表示新的类描述开始

·00 0F表示该类的类路径的长度,即com.test.Person的长度。0X0F表示15,代表接下来的15个字节都是包名的组成部分;

·跳过包名的字符,接下来的8个字节为序列化id的值;

·接下来的02代表的是对象实现的是Serializable接口,如果为04代表实现Externalizable,0x10为枚举类型;

·接下来的0x00 0x03代表的是属性的个数,目前有age,weight和name,刚好是3个;

第三部分:属性描述信息

·49 00 03 61 67 65  :49对应的是I,代表的是int,表示该字段是int类型,00 03代表字段的长度为3,61 67 65对应的是age,代表该字段名是age;

·49 00 06 77 65 69 67 68 74 :49表示该类型是int,00 06表示该字段名长度为6,接下来6个字符代表weight;

·4C 00 04 6E 61 6D 65  :4C表示L,代表域类型,接下来00 04代表字段名长度,接下来4个字符为name;

·74 00 12 :0x74代表的是新的字符串,接下来的00 12代表接下来的18个字符是该字符串的签名,即Ljava/lang/String;

·78 70 :0x78代表对象块结束标签,0x70代表没有超类;

第四部分:属性值

由于第三部分已经将属性进行了描述,此处的顺序也是按照第三部分解析的顺序来设定值。基本类型直接设置,int为4个字节

·00 00 00 12 的值对应的是第三部分的age,代表18,符合;

·00 00 00 78 对应的是第三部分的weight,为120,符合;

·74  00 0E 74 65 73 74 50 65 72 73 6F 6E 4E 61 6D 65  :由于name是字符串,所以此处0x74标记了字符串,接下来的00 0E代表接下来的14个字节为name的值,解析为testPersonName,符合。

上一篇:java序列化与反序列化进阶(一)

你可能感兴趣的:(java序列化与反序列化进阶(二))