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
Java序列化机制原理的更多相关文章
- Java序列化机制和原理及自己的理解
Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.Java序列化API提供一 ...
- Java序列化机制和原理
Java序列化算法透析 Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.Java序列化API提供一 ...
- Java序列化机制
java的序列化机制支持将对象序列化为本地文件或者通过网络传输至别处, 而反序列化则可以读取流中的数据, 并将其转换为java对象. 被序列化的类需要实现Serializable接口, 使用Objec ...
- hadoop序列化机制与java序列化机制对比
1.采用的方法: java序列化机制采用的ObjectOutputStream 对象上调用writeObject() 方法: Hadoop 序列化机制调用对象的write() 方法,带一个DataOu ...
- 输入和输出--java序列化机制
对象的序列化 什么是Java对象的序列化? 对象序列化的目标是将对象保存到磁盘上,或允许在网络中直接传输对象.对象序列化机制允许把内存中的Java对象转换成与平台无关的二进制流,从而保存或者传输.其他 ...
- Java序列化机制剖析
本文转载自longdick的博文<Java序列化算法透析>,原文地址:http://longdick.iteye.com Java序列化算法透析 Serialization(序列化)是一种 ...
- Java I/O系统学习系列五:Java序列化机制
在Java的世界里,创建好对象之后,只要需要,对象是可以长驻内存,但是在程序终止时,所有对象还是会被销毁.这其实很合理,但是即使合理也不一定能满足所有场景,仍然存在着一些情况,需要能够在程序不运行的情 ...
- ReflectASM-invoke,高效率java反射机制原理
前言:前段时间在设计公司基于netty的易用框架时,很多地方都用到了反射机制.反射的性能一直是大家有目共睹的诟病,相比于直接调用速度上差了很多.但是在很多地方,作为未知通用判断的时候,不得不调用反射类 ...
- 细看Java序列化机制
概况 在程序中为了能直接以 Java 对象的形式进行保存,然后再重新得到该 Java 对象,这就需要序列化能力.序列化其实可以看成是一种机制,按照一定的格式将 Java 对象的某状态转成介质可接受的形 ...
随机推荐
- 微服务-封装-docker by daysn大雄
目录 序言一.什么是容器二.docker入门 2.1安装启动2.2docker使用 2.2.1 helloworld 2.2.2 容器 2.2.3 镜像 2.2.4 容器的连接 序言 虚拟化一 ...
- php加密
域名授权函数 function allow_doamin(){ $is_allow=false; $url=trim($_SERVER['SERVER_NAME']); $arr_a ...
- 关于Java的特点之继承
继承--解决之道 继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类(比如刚才的Student),在父类中定义这些相同的属性和方法,所 ...
- Problem F: 平面上的点——Point类 (VI)
Description 在数学上,平面直角坐标系上的点用X轴和Y轴上的两个坐标值唯一确定.现在我们封装一个“Point类”来实现平面上的点的操作. 根据“append.cc”,完成Point类的构造方 ...
- nginx——Nginx 处理事件模型
Nginx 的连接处理机制在不同的操作系统会采用不同的 I/O 模型,要根据不同的系统选择不同的事件处理模型,可供选择的事件处理模型有:kqueue .rtsig .epoll ./dev/poll ...
- CMD命令,动态执行存储或DML命令
--exec master..xp_cmdshell CMD命令 --EXECUTE sys.sp_sqlexec 执行存储 --EXEC sp_executesql 执行DML语句
- es6学习日记2
1.字符串扩展 字符串的遍历器接口 for (let codePoint of 'foo') { console.log(codePoint) } // "f" // " ...
- A Statistical Model for Scientific Readability-paper
Authors: Luo SiCarnegie Mellon University, Pittsburgh, PA Jamie CallanCarnegie Mellon University, Pi ...
- 监控端口是否开放,端口未开放关闭虚拟ip,端口开放启动虚拟IP
#!/bin/bash#该脚本监控本机的一个端口,当端口异常时,停止lvs的本地ip直到恢复.该脚本依托于lvs.sh启动脚本#目前只支持监控1个vip #定义常用变量#配置检查的ip以及端口chec ...
- Linux之ls
命令功能: ls是list的简写,列出目录下的内容 命令格式: ls [OPTION]... [FILE]... 命令参数: -a,--all 不忽略以“.”开头的隐藏文件 -A, --almo ...