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

Java序列化机制原理的更多相关文章

  1. Java序列化机制和原理及自己的理解

    Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.Java序列化API提供一 ...

  2. Java序列化机制和原理

    Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.Java序列化API提供一 ...

  3. Java序列化机制

    java的序列化机制支持将对象序列化为本地文件或者通过网络传输至别处, 而反序列化则可以读取流中的数据, 并将其转换为java对象. 被序列化的类需要实现Serializable接口, 使用Objec ...

  4. hadoop序列化机制与java序列化机制对比

    1.采用的方法: java序列化机制采用的ObjectOutputStream 对象上调用writeObject() 方法: Hadoop 序列化机制调用对象的write() 方法,带一个DataOu ...

  5. 输入和输出--java序列化机制

    对象的序列化 什么是Java对象的序列化? 对象序列化的目标是将对象保存到磁盘上,或允许在网络中直接传输对象.对象序列化机制允许把内存中的Java对象转换成与平台无关的二进制流,从而保存或者传输.其他 ...

  6. Java序列化机制剖析

    本文转载自longdick的博文<Java序列化算法透析>,原文地址:http://longdick.iteye.com Java序列化算法透析 Serialization(序列化)是一种 ...

  7. Java I/O系统学习系列五:Java序列化机制

    在Java的世界里,创建好对象之后,只要需要,对象是可以长驻内存,但是在程序终止时,所有对象还是会被销毁.这其实很合理,但是即使合理也不一定能满足所有场景,仍然存在着一些情况,需要能够在程序不运行的情 ...

  8. ReflectASM-invoke,高效率java反射机制原理

    前言:前段时间在设计公司基于netty的易用框架时,很多地方都用到了反射机制.反射的性能一直是大家有目共睹的诟病,相比于直接调用速度上差了很多.但是在很多地方,作为未知通用判断的时候,不得不调用反射类 ...

  9. 细看Java序列化机制

    概况 在程序中为了能直接以 Java 对象的形式进行保存,然后再重新得到该 Java 对象,这就需要序列化能力.序列化其实可以看成是一种机制,按照一定的格式将 Java 对象的某状态转成介质可接受的形 ...

随机推荐

  1. 面试题--Java

    &与&&区别? &与&&都是逻辑运算符,都是判断两边为真则为真,两边为假则为假,但是&&如果第一个条件不成立的话,后面的将不会再继续执行 ...

  2. atom插件安装失败解决方法

    在atom 上下载插件失败,可以用下面的方法. 1.找到C:/Users/你的用户名/.atom/packages/文件夹内 2.在.atom packages 目录下 使用gitbash 3.git ...

  3. Linux磁盘空间满了的排查与解决思路

    block正常满 (磁盘实际不足)inode 满 大量的小文件block 满 文件没有被彻底删除(硬链接数0 进程调用数不为0) 解放方法: 1 查看df -h 磁盘使用量根据占用量大小逐步逐步排查 ...

  4. angular2 pipe实现搜索结果中的搜索关键字高亮

    效果图如下 1.声明一个pipe import {Pipe, Injectable, PipeTransform} from '@angular/core';import { DomSanitizer ...

  5. 最短路,floyd算法,图的最短路径

    题目描述: 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shirt.但是每当我们的工作人员把上百件的衣服从商店运回到赛场的时候,却是非常累的!所以现在他们想要寻找最短的从商店到赛场的路线 ...

  6. 2--Postman脚本介绍

    Postman是访问各种API的客户端.它的强大之处在于其允许在对某一个request访问的之前和之后分别运行自定义的一段Javascript脚本,可以将数条request连结成一个流程完成一体化测试 ...

  7. 新建一个self hosted Owin+ SignalR Project(1)

    OWIN是Open Web Server Interface for .Net 的首字母缩写,他的定义如下: OWIN在.NET Web Server 与Web Application之间定义了一套标 ...

  8. js调用app启动页

    第一步:添加js $(function () { var ua = window.navigator.userAgent.toLowerCase(); //微信 if(ua.match(/MicroM ...

  9. win10企业版2016长期服务版本激活

    右键左下角Windows开始图标  ——>  单击  命令提示符(管理员)A 粘贴如下代码到dos窗口: slmgr /ipk DCPHK-NFMTC-H88MJ-PFHPY-QJ4BJ slm ...

  10. 全志A33 lichee 搭建Qt App开发环境编写helloworld

    开发平台 * 芯灵思SinlinxA33开发板 淘宝店铺: https://sinlinx.taobao.com/ 嵌入式linux 开发板交流 QQ:641395230 Step 1 在虚拟机(Ce ...