java 序列化 原理_Java序列化机制原理

Java序列化就是将一个对象转化为一个二进制表示的字节数组,通过保存或则转移这些二进制数组达到持久化的目的。要实现序列化,需要实现java.io.Serializable接口。反序列化是和序列化相反的过程,就是把二进制数组转化为对象的过程。在反序列化的时候,必须有原始类的模板才能将对象还原。从这个过程我们可以猜测到,序列化过程并不想class文件那样保存类的完整的结构信息。下面我们以一个简单的例子来看一下,序列化的时候都保存了哪些信息。代码如下:

package com.ysl;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.ObjectOutputStream;

import java.io.Serializable;

public class SerializableTest implements Serializable{

private static final long serialVersionUID = -1L;

public int num = 2018;

public static void main(String[] args){

try {

FileOutputStream fos = new FileOutputStream("serializable");

ObjectOutputStream oos = new ObjectOutputStream(fos);

SerializableTest test = new SerializableTest();

oos.writeObject(test);

oos.flush();

oos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

序列化后的二进制字节数据如下:

aced 0005 7372 0018 636f 6d2e 7973 6c2e

5365 7269 616c 697a 6162 6c65 5465 7374

ffff ffff ffff ffff 0200 0149 0003 6e75

6d78 7000 0007 e2

上述的内容分为一下几个部分:

第一部分是序列化文件头

AC ED :STREAM_MAGIC声明使用了序列化协议

00 05 :STREAM_VERSION序列化协议版本

73 :TC_OBJECT声明这是一个新的对象

第二部分是序列化的类的描述,在这里是SerializableTest

72 :TC_CLASSDESC声明这里开始一个新的class

00 18:class名字的长度是24个字节

636f 6d2e 7973 6c2e 5365 7269 616c 697a 6162 6c65 5465 7374:SerializableTest的完整类名

ffff ffff ffff ffff:serialVersionUID,序列化ID,如果没有指定,则会由算法随机生成一个8字节的ID

02 :标记号,声明该类支持序列化

00 01:该类所包含的域的个数为1

第三部分是对象中各个属性的描述

49:域类型,49代表I,也就是int类型

00 03:域名字的长度为3

6e 75 6d:num属性的名称

第四部分为对象的父类信息描述

SerializableTest没有父类,如果有,和第二部分的描述相同

78 :TC_ENDBLOCKDATA,对象块的结束标志

70:TC_NUL:说明没有其他超类的标志

第五部分为对象属性的实际值

如果属性是一个对象,那么这里还将序列化这个对象,规则和第二部分一样

00 0007 e2:数值2018

虽然Java的序列化能够保证对象状态的持久保存,但是遇到一些对象结构复杂的情况还是比较难处理的,下面是对一些复杂情况的总结:

当父类实现了Serializable接口的时候,所有的子类都能序列化

子类实现了Serializable接口,父类没有,父类中的属性不能被序列化(不报错,但是数据会丢失)

如果序列化的属性是对象,对象必须也能序列化,否则会报错

反序列化的时候,如果对象的属性有修改或则删减,修改的部分属性会丢失,但是不会报错

在反序列化的时候serialVersionUID被修改的话,会反序列化失败

在存Java环境下使用Java的序列化机制会支持的很好,但是在多语言环境下需要考虑别的序列化机制,比如xml,json,或则protobuf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值