Java序列化

转自 https://www.cnblogs.com/senlinyang/p/8204752.html
感谢 木易森林 的总结

transient关键字:让某些被修饰的成员属性变量不被序列化

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值