java序列化原理与算法

合集下载

Java中关键字transient引出序列化与反序列化

Java中关键字transient引出序列化与反序列化

Java中关键字transient引出序列化与反序列化⼀:transient(临时的)关键字 1.transient关键字只能修饰变量,⽽不能修饰⽅法和类。

注意,本地变量是不能被transient关键字修饰的。

2.被transient关键字修饰的变量不能被序列化,⼀个静态变量不管是否被transient修饰,均不能被序列化。

3.⼀旦变量被transient修饰,变量将不再是持久化的⼀部分,该变量内容在序列化后⽆法获得访问。

也可以认为在将持久化的对象反序列化后,被transient修饰的变量将按照普通类成员变量⼀样被初始化。

⼆:java对象序列化 当两个进程在进⾏远程通信时,彼此可以发送各种类型的数据。

⽆论是何种类型的数据,都会以⼆进制序列的形式在⽹络上传送。

发送⽅需要把这个java对象转化为字节序列,才能在⽹络上传送;接收⽅则需要把字节序列再恢复为java对象。

只能将⽀持 java.io.Serializable 接⼝的对象写⼊流中。

每个 serializable 对象的类都被编码,编码内容包括类名和类签名、对象的字段值和数组值,以及从初始对象中引⽤的其他所有对象的闭包。

1.概念 序列化:把java对象转化为字节序列的过程。

发序列化:字节序列恢复为java对象的过程。

2.⽤途 对象的序列化主要有两种⽤途: 1)把对象的字节序列永久地保存到磁盘上,通常放到⼀个⽂件中。

2)在⽹络上传送对象的字节序列。

3.对象序列化代码⽰例 ================================================================== 结果: 4.说明 读取对象的顺序与写⼊时的顺序要⼀致。

对象的默认序列化机制写⼊的内容是:对象的类,类签名,以及⾮瞬态(transient)和⾮静态字段(static)的值。

Java对象的序列化与反序列化-Json篇

Java对象的序列化与反序列化-Json篇

Java对象的序列化与反序列化-Json篇说到Java对象的序列化与反序列化,我们⾸先想到的应该是Java的Serializable接⼝,这玩意在两个系统之间的DTO对象⾥⾯可能会⽤到,⽤于系统之间的数据传输。

或者在RPC(远程⽅法调⽤)时可能会⽤到。

但其实若是⽤于数据传输,xml和json两种数据格式⽤得更多⼀些。

但是为什么不⽤XStream呢,XStream确实好⽤,但是在Applet环境下可以使⽤的xml类库也就只有jdom了,连dom4j在Applet环境下都没有权限使⽤(Java反射的某些特性是需要权限的,Applet的安全机制不允许)。

扯远了,本⽂要说的是Java对象与Json的相互转换。

⽬前Java常⽤的Json类库有3种,即fastjson、jackson和gson,分别介绍如何将⼀个Java对象转换成Json和将⼀个Json字符串转换成Java对象,其实它们的⽤法⼤同⼩异。

⼀、⾸先看Maven依赖⼆、需要序列化的POJO和初始化代码三、fastjson的使⽤四、jackson的使⽤五、gson的使⽤⼀、⾸先看Maven依赖若不会maven,请参考Maven的基本⽤法:1 <!-- json -->2 <!-- 引⼊fastjson依赖 -->3 <dependency>4 <groupId>com.alibaba</groupId>5 <artifactId>fastjson</artifactId>6 <version>1.2.12</version>7 </dependency>8 <!-- 引jackson依赖 -->9 <!-- jackson核⼼包,必选,提供基于“流模式”解析的API -->10 <dependency>11 <groupId>com.fasterxml.jackson.core</groupId>12 <artifactId>jackson-core</artifactId>13 <version>2.7.4</version>14 </dependency>15 <!-- jackson注解包,可选,提供注解功能 -->16 <dependency>17 <groupId>com.fasterxml.jackson.core</groupId>18 <artifactId>jackson-annotations</artifactId>19 <version>2.7.4</version>20 </dependency>21 <!-- jackson数据绑定包,可选,提供基于“对象绑定”和“树模型”相关API -->22 <dependency>23 <groupId>com.fasterxml.jackson.core</groupId>24 <artifactId>jackson-databind</artifactId>25 <version>2.7.4</version>26 </dependency>27 <!-- 引⼊gson依赖 -->28 <dependency>29 <groupId>com.google.code.gson</groupId>30 <artifactId>gson</artifactId>31 <version>2.6.2</version>32 </dependency>⼆、需要序列化的POJO和初始化代码以下3种类库的使⽤均使⽤下⾯这个POJO1public class User {2public User(){}3private String id;4private String name;5private String password;6public String getId() {7return id;8 }9public void setId(String id) {10this.id = id;11 }12public String getName() {13return name;14 }15public void setName(String name) { = name;17 }18public String getPassword() {19return password;20 }21public void setPassword(String password) {22this.password = password;23 }24 @Override25public String toString() {26return"User [id=" + id + ", name=" + name + ", password=" + password27 + "]";28 }29 }1/**2 * 初始化User对象3 * @return user4*/5private static User initUser(){6 User user = new User();7 user.setId("1");8 user.setName("jison");9 user.setPassword("jison");10return user;11 }三、fastjson的使⽤fastjson的主要⼯具类是JSON,以下代码实现Java对象的序列化与反序列化1// 将Java对象序列化为Json字符串2 String objectToJson = JSON.toJSONString(initUser());3 System.out.println(objectToJson);4// 将Json字符串反序列化为Java对象5 User user = JSON.parseObject(objectToJson, User.class);6 System.out.println(user);四、jackson的使⽤jackson我们经常⽤到的是它的数据绑定包下的ObjectMapper类,以下代码实现Java对象的序列化与反序列化ObjectMapper objectMapper = new ObjectMapper();// 将Java对象序列化为Json字符串String objectToJson = objectMapper.writeValueAsString(initUser());System.out.println(objectToJson);// 将Json字符串反序列化为Java对象User user = objectMapper.readValue(objectToJson, User.class);System.out.println(user);五、gson的使⽤gson的主要⼯具类是Gson,使⽤GsonBuilder构造,以下代码实现Java对象的序列化与反序列化1 Gson gson = new GsonBuilder().create();2// 将Java对象序列化为Json字符串3 String objectToJson = gson.toJson(initUser());4 System.out.println(objectToJson);5// 将Json字符串反序列化为Java对象6 User user = gson.fromJson(objectToJson, User.class);7 System.out.println(user);以上3种json类库的完整代码如下:1public class JsonUtils {23/**4 * 初始化User对象5 * @return user6*/7private static User initUser(){8 User user = new User();9 user.setId("1");10 user.setName("jison");11 user.setPassword("jison");12return user;13 }1415public static void main(String[] args) throws Exception {16// fastjson⽤法17 fastjson();18// jackson⽤法19 jackson();20// gson⽤法21 gson();22 }2324private static void fastjson(){25// 将Java对象序列化为Json字符串26 String objectToJson = JSON.toJSONString(initUser());27 System.out.println(objectToJson);28// 将Json字符串反序列化为Java对象29 User user = JSON.parseObject(objectToJson, User.class);30 System.out.println(user);31 }3233private static void jackson() throws Exception{34 ObjectMapper objectMapper = new ObjectMapper();35// 将Java对象序列化为Json字符串36 String objectToJson = objectMapper.writeValueAsString(initUser());37 System.out.println(objectToJson);38// 将Json字符串反序列化为Java对象39 User user = objectMapper.readValue(objectToJson, User.class);40 System.out.println(user);41 }4243private static void gson(){44 Gson gson = new GsonBuilder().create();45// 将Java对象序列化为Json字符串46 String objectToJson = gson.toJson(initUser());47 System.out.println(objectToJson);48// 将Json字符串反序列化为Java对象49 User user = gson.fromJson(objectToJson, User.class);50 System.out.println(user);51 }52 }。

序列化与反序列化的原理以及利用和防御

序列化与反序列化的原理以及利用和防御

序列化与反序列化的原理以及利⽤和防御1、序列化和反序列化的概念序列化:把对象转换为字节序列的过程称为对象的序列化。

反序列化:把字节序列恢复为对象的过程称为对象的反序列化。

序列化就是把对象转换成字节流,便于保存在内存、⽂件、数据库中;反序列化即逆过程,由字节流还原成对象。

Java中的ObjectOutputStream类的writeObject()⽅法可以实现序列化,类ObjectInputStream类的readObject()⽅法⽤于反序列化。

下⾯是将字符串对象先进⾏序列化,存储到本地⽂件,然后再通过反序列化进⾏恢复如果Java应⽤对⽤户输⼊,即不可信数据做了反序列化处理,那么攻击者可以通过构造恶意输⼊,让反序列化产⽣⾮预期的对象,⾮预期的对象在产⽣过程中就有可能带来任意代码执⾏问题的根源在于类ObjectInputStream在反序列化时,没有对⽣成的对象的类型做限制;假若反序列化可以设置Java类型的⽩名单2、序列化的⽬的与⽤到序列化的情况当你想把的内存中的对象状态保存到⼀个⽂件中或者数据库中时候;当你想⽤套接字在⽹络上传送对象的时候;当你想通过RMI传输对象的时候;2.1对象序列化的步骤如下(1)创建对象输⼊流,它可以包装⼀个其他类型的⽬标输⼊流,例如:⽂件输出流。

(2)通过对象输⼊流的writeObject()⽅法写对象。

2.2.对象的反序列化如下:(1)创建对象输⼊流,同样的,可以包含其他类型的⽬标输出流,例如:⽂件输⼊流。

(2)通过对象输⼊流的readObject()⽅法读取对象。

3、漏洞挖掘基本⼿段:从可控数据的反序列化或间接的反序列化接⼝⼊⼿,在此基础上尝试构造序列化对象。

⾸先拿到⼀个Java应⽤,需要找到⼀个接受外部输⼊的序列化对象的接收点,即反序列化漏洞的触发点。

我们可以通过审计源码中对反序列化函数的调⽤(例如readObject())来寻找,也可以直接通过对应⽤交互流量进⾏抓包,查看流量中是否包含java序列化数据来判断,java序列化数据的特征为以标记(ac ed 00 05)开头。

java2进制序列化_(二十一)、Java序列化与反序列化

java2进制序列化_(二十一)、Java序列化与反序列化

java2进制序列化_(⼆⼗⼀)、Java序列化与反序列化⼀、什么是序列化与反序列化?java 序列化是指把java 对象转换成字节序列的过程;java 反序列化是指把字节序列恢复为java 对象的过程。

⼆、为什么要⽤序列化与反序列化在 为什么要⽤序列化与反序列化 之前我们先了解⼀下对象序列化的两种⽤途:1、把对象的字节序列永久地保存到硬盘上,通常存放在⼀个⽂件中;2、在⽹络上传送对象的字节序列。

我们可以想象⼀下如果没有序列化之前,⼜是怎样⼀种情景呢?举个栗⼦:Web 服务器中的 Session 会话对象,当有10万⽤户并发访问,就有可能出现10万个 Session 对象,显然这种情况内存可能是吃不消的。

于是 Web 容器就会把⼀些 Session 先序列化,让他们离开内存空间,序列化到硬盘中,当需要调⽤时,再把保存在硬盘中的对象还原到内存中。

我们知道,当两个进程进⾏远程通信时,彼此可以发送各种类型的数据,包括⽂本、图⽚、⾳频、视频等, ⽽这些数据都会以⼆进制序列的形式在⽹络上传送。

同样的序列化与反序列化则实现了 进程通信间的对象传送,发送⽅需要把这个Java对象转换为字节序列,才能在⽹络上传送;接收⽅则需要把字节序列再恢复为Java对象。

初步总结:Java 序列化和反序列化,其⼀,实现了数据的持久化,通过序列化可以把数据永久的保存在硬盘上;其⼆,利⽤序列化实现远程通信,即在⽹络上传递对象的字节序列。

三、如何实现序列化与反序列化?1、JDK类库中序列化API使⽤到JDK中关键类 ObjectOutputStream(对象输出流) 和ObjectInputStream(对象输⼊流)ObjectOutputStream 类中:通过使⽤ writeObject(Object object) ⽅法,将对象以⼆进制格式进⾏写⼊。

ObjectInputStream 类中:通过使⽤ readObject()⽅法,从输⼊流中读取⼆进制流,转换成对象。

java反序列化ctf题目

java反序列化ctf题目

java反序列化ctf题目摘要:1.Java 反序列化CTF 题目概述2.Java 反序列化的原理3.Java 反序列化CTF 题目的解题思路4.Java 反序列化CTF 题目的实践案例5.总结正文:1.Java 反序列化CTF 题目概述CTF(Capture The Flag)是一种网络安全竞赛形式,选手通过攻防各种网络安全技术来获取题目的答案。

在CTF 题目中,有一类题目涉及到Java 反序列化,它要求参赛者利用Java 反序列化的原理,对给定的数据进行解析和还原。

这类题目具有较高的技术难度,需要参赛者具备扎实的Java 基础知识和对序列化机制的深入理解。

2.Java 反序列化的原理Java 反序列化是指将序列化后的数据恢复为原始对象的过程。

序列化是将Java 对象转换为字节码的过程,便于存储和传输。

而反序列化则是将字节码还原为Java 对象。

这个过程主要依赖于java.io.ObjectInputStream 类,它提供了readObject() 方法来实现对象的反序列化。

在Java 反序列化过程中,需要注意以下几点:- 反序列化过程中会触发类的构造函数,因此需要确保传入的参数类型与构造函数声明的参数类型一致。

- 反序列化过程中会根据类名动态加载类,因此需要确保类路径正确。

- 反序列化过程中可能会遇到继承关系,需要正确处理继承关系以避免类循环。

3.Java 反序列化CTF 题目的解题思路面对Java 反序列化CTF 题目,参赛者需要首先分析题目给出的数据格式,了解序列化的规则。

然后通过编写代码模拟反序列化过程,将数据还原为原始对象。

具体的解题思路如下:- 分析题目给出的数据格式,了解序列化规则。

- 根据序列化规则,编写代码实现反序列化过程。

- 处理继承关系,确保反序列化过程中的类循环问题。

- 验证反序列化结果,确保正确还原题目要求的对象。

4.Java 反序列化CTF 题目的实践案例假设有一道Java 反序列化CTF 题目,题目要求参赛者将给定的字节码数据还原为对应的Java 对象。

jackson序列化原理

jackson序列化原理

jackson序列化原理Jackson是一个流行的Java库,用于将Java对象序列化为JSON 格式,反之亦然。

在这篇文章中,我们将深入探讨Jackson序列化的原理。

Jackson的核心类是ObjectMapper,它是Java对象和JSON之间转换的中心。

当我们使用ObjectMapper将Java对象序列化为JSON 时,Jackson会执行下列操作:1. 将Java对象转换为JsonNode对象首先,Jackson将Java对象转换为JsonNode对象。

JsonNode是Jackson中一个核心的、轻量级的JSON对象,它是一个类似于树结构的对象。

JsonNode对象包含了Java对象中的所有属性和值。

Jackson使用JsonNode对象来构建JSON格式的字符串。

2. 构建JSON格式的字符串接下来,Jackson将JsonNode对象转换为JSON格式的字符串。

这个过程通常称为序列化。

Jackson使用一组规则来序列化JsonNode 对象成一个JSON格式的字符串。

序列化的规则包括:如何处理空值、如何处理日期、如何处理集合等等。

3. 输出JSON格式的字符串最后,Jackson将JSON格式的字符串输出到指定的目标。

这个目标可以是一个文件、一个网络连接或者一个字符串缓冲区。

当我们使用ObjectMapper将JSON转换成Java对象时,Jackson 会执行相反的过程:1. 读取JSON字符串首先,Jackson会读取JSON字符串,这个字符串可以来自文件、网络连接或者一个字符串缓冲区。

2. 解析JSON字符串接下来,Jackson将JSON字符串解析成JsonNode对象。

这个过程通常称为反序列化。

Jackson使用一组规则来解析JSON格式的字符串,并构建JsonNode对象。

3. 将JsonNode对象转换为Java对象最后,Jackson将JsonNode对象转换为Java对象。

serialize计算机术语

serialize计算机术语

serialize计算机术语序列化是计算机术语中的一个重要概念,它在计算机科学中有着广泛的应用。

本文将从不同角度解释和探讨序列化的概念、原理、应用以及与之相关的技术。

一、什么是序列化序列化是指将数据结构或对象转为可存储或传输的形式的过程。

在计算机中,数据通常以二进制的方式存储和传输,而序列化将数据转换为二进制流的形式,使得数据可以被存储到文件中或通过网络进行传输。

反之,反序列化则是将序列化后的数据恢复为原来的数据结构或对象的过程。

二、序列化的原理序列化的原理是将数据按照一定的规则进行编码,将编码后的数据写入文件或通过网络传输。

在进行序列化时,需要考虑数据的类型、结构和顺序等信息,以便在反序列化时正确地恢复数据。

常见的序列化方法有二进制序列化、XML序列化和JSON序列化等。

三、序列化的应用1. 数据持久化:通过序列化,可以将内存中的数据保存到磁盘中,以实现数据的持久化存储。

例如,在数据库中存储对象时,通常需要先将对象序列化为二进制流,然后存储到数据库中。

2. 远程通信:在分布式系统中,不同计算机之间需要进行数据的传输和共享。

通过序列化,可以将数据转换为二进制流,然后通过网络传输到远程计算机,实现远程通信和数据共享。

3. 缓存和消息队列:在缓存系统和消息队列中,常常需要将数据进行序列化,以便于在不同组件之间进行传递和处理。

通过序列化,可以将数据转换为二进制流,然后存储到缓存中或发送到消息队列中。

4. 对象传递:在面向对象编程中,对象是程序的基本单元,通过序列化,可以将对象转换为二进制流,然后在不同的程序或计算机之间传递和共享对象。

四、序列化的相关技术1. Java序列化:Java提供了自带的序列化机制,通过实现Serializable接口,可以将Java对象序列化为二进制流,并进行持久化存储或网络传输。

同时,Java也提供了反序列化的机制,可以将二进制流恢复为原来的Java对象。

2. XML序列化:XML是一种可扩展标记语言,通过使用标签和属性来表示数据结构和内容。

kryo序列化原理

kryo序列化原理

kryo序列化原理
Kryo序列化是一种高效的Java序列化库,它可以将 Java 对象序列化为一个紧凑的二进制格式,从而实现快速的序列化和反序列化。

Kryo 序列化的原理主要包括以下几个方面:
1. 类注册
Kryo 序列化需要事先注册序列化的 Java 对象的类信息,这样
才能在序列化和反序列化时正确地处理对象。

2. 字段序列化
Kryo 序列化将 Java 对象的字段序列化为一个字节数组,然后
将这个字节数组写入到输出流中。

在反序列化时,Kryo 序列化会从
输入流中读取字节数组,并将其反序列化为 Java 对象的字段。

3. 压缩算法
Kryo 序列化使用了一种基于 LZF 算法的压缩算法,可以将序列化后的字节数组进行压缩,从而减少序列化后的数据大小。

4. 缓存优化
Kryo 序列化使用了一种缓存技术,可以将序列化后的 Java 对
象缓存起来,从而避免重复序列化和反序列化相同的对象,从而提高了序列化和反序列化的效率。

总的来说,Kryo 序列化的原理是通过注册对象类信息、字段序
列化、压缩算法和缓存优化等技术,实现了高效的 Java 对象序列化和反序列化。

- 1 -。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Java序列化原理和算法总结:java中序列化算法的顺序:1、子类的类信息描述2、子类的字段信息描述(如果遇到类对象的属性,暂时用string的指针表示)3、父类的类信息描述4、父类的字段信息描述5、对父类的字段信息进行赋值6、对子类的字段信息进行赋值7、发现子类的字段为类对象时,描述该类对象,并查找该类对象的父类,以以上方式描述,然后赋值。

本文讲解了Java序列化的机制和原理。

从文中你可以了解如何序列化一个对象,什么时候需要序列化以及Java序列化的算法。

有关Java对象的序列化和反序列化也算是Java基础的一部分,下面对Java序列化的机制和原理进行一些介绍。

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

Java序列化API提供一种处理对象序列化的标准机制。

在这里你能学到如何序列化一个对象,什么时候需要序列化以及Java序列化的算法,我们用一个实例来示范序列化以后的字节是如何描述一个对象的信息的。

序列化的必要性Java中,一切都是对象,在分布式环境中经常需要将Object从这一端网络或设备传递到另一端。

这就需要有一种可以在两端传输数据的协议。

Java序列化机制就是为了解决这个问题而产生。

如何序列化一个对象一个对象能够序列化的前提是实现Serializable接口,Serializable接口没有方法,更像是个标记。

有了这个标记的Class就能被序列化机制处理。

import java.io.Serializable;class TestSerial implements Serializable {public byte version = 100;public byte count = 0;}然后我们写个程序将对象序列化并输出。

ObjectOutputStream能把Object输出成Byte流。

我们将Byte流暂时存储到temp.out文件里。

public static void main(String args[]) throws IOException {FileOutputStream fos = new FileOutputStream("temp.out");ObjectOutputStream oos = new ObjectOutputStream(fos);TestSerial ts = new TestSerial();oos.writeObject(ts);oos.flush();oos.close();如果要从持久的文件中读取Bytes重建对象,我们可以使用ObjectInputStream。

public static void main(String args[]) throws IOException {FileInputStream fis = new FileInputStream("temp.out");ObjectInputStream oin = new ObjectInputStream(fis); TestSerial ts = (TestSerial) oin.readObject();System.out.println("version="+ts.version);}执行结果为 100.对象的序列化格式将一个对象序列化后是什么样子呢?打开刚才我们将对象序列化输出的temp.out文件,以16进制方式显示。

内容应该如下:AC ED 00 05 73 72 00 0A 53 65 72 69 61 6C 54 6573 74 A0 0C 34 00 FE B1 DD F9 02 00 02 42 00 0563 6F 75 6E 74 42 00 07 76 65 72 73 69 6F 6E 7870 00 64这一坨字节就是用来描述序列化以后的TestSerial对象的,我们注意到TestSerial类中只有两个域:public byte version = 100;public byte count = 0;且都是byte型,理论上存储这两个域只需要2个byte,但是实际上temp.out占据空间为51bytes,也就是说除了数据以外,还包括了对序列化对象的其他描述。

Java的序列化算法序列化算法一般会按步骤做如下事情:◆将对象实例相关的类元数据输出。

◆递归地输出类的超类描述直到不再有超类。

◆类元数据完了以后,开始从最顶层的超类开始输出对象实例的实际数据值。

◆从上至下递归输出实例的数据我们用另一个更完整覆盖所有可能出现的情况的例子来说明:class parent implements Serializable {int parentVersion = 10;}class contain implements Serializable{int containVersion = 11;}public class SerialTest extends parent implements Serializable {int version = 66;contain con = new contain();public int getVersion() {return version;}public static void main(String args[]) throws IOException {FileOutputStream fos = new FileOutputStream("temp.out");ObjectOutputStream oos = new ObjectOutputStream(fos);SerialTest st = new SerialTest();oos.writeObject(st);oos.flush();oos.close();}}这个例子是相当的直白啦。

SerialTest类实现了Parent超类,内部还持有一个Container对象。

序列化后的格式如下:AC ED 00 05 73 72 00 0A 53 65 72 69 61 6C 54 6573 74 05 52 81 5A AC 66 02 F6 02 00 02 49 00 0776 65 72 73 69 6F 6E 4C 00 03 63 6F 6E 74 00 094C 63 6F 6E 74 61 69 6E 3B 78 72 00 06 70 61 7265 6E 74 0E DB D2 BD 85 EE 63 7A 02 00 01 49 000D 70 61 72 65 6E 74 56 65 72 73 69 6F 6E 78 7000 00 00 0A 00 00 00 42 73 72 00 07 63 6F 6E 7461 69 6E FC BB E6 0E FB CB 60 C7 02 00 01 49 000E 63 6F 6E 74 61 69 6E 56 65 72 73 69 6F 6E 7870 00 00 00 0B我们来仔细看看这些字节都代表了啥。

开头部分,见颜色:AC ED: STREAM_MAGIC. 声明使用了序列化协议.00 05: STREAM_VERSION. 序列化协议版本.0x73: TC_OBJECT. 声明这是一个新的对象.序列化算法的第一步就是输出对象相关类的描述。

例子所示对象为SerialTest类实例,因此接下来输出SerialTest类的描述。

见颜色:0x72: TC_CLASSDESC. 声明这里开始一个新Class。

00 0A: Class名字的长度.53 65 72 69 61 6c 54 65 73 74: SerialTest,Class类名.05 52 81 5A AC 66 02 F6: SerialVersionUID, 序列化ID,如果没有指定,则会由算法随机生成一个8byte的ID.0x02: 标记号. 该值声明该对象支持序列化。

00 02: 该类所包含的域个数。

接下来,算法输出其中的一个域,int version=66;见颜色:0x49: 域类型. 49 代表"I", 也就是Int.00 07: 域名字的长度.76 65 72 73 69 6F 6E: version,域名字描述.然后,算法输出下一个域,contain con = new contain();这个有点特殊,是个对象。

描述对象类型引用时需要使用JVM的标准对象签名表示法,见颜色:0x4C: 域的类型.00 03: 域名字长度.63 6F 6E: 域名字描述,con0x74: TC_STRING. 代表一个new String.用String来引用对象。

00 09: 该String长度.4C 63 6F 6E 74 61 69 6E 3B: Lcontain;, JVM的标准对象签名表示法.0x78: TC_ENDBLOCKDATA,对象数据块结束的标志.接下来算法就会输出超类也就是Parent类描述了,见颜色:0x72: TC_CLASSDESC. 声明这个是个新类.00 06: 类名长度.70 61 72 65 6E 74: parent,类名描述。

0E DB D2 BD 85 EE 63 7A: SerialVersionUID, 序列化ID.0x02: 标记号. 该值声明该对象支持序列化.00 01: 类中域的个数.下一步,输出parent类的域描述,int parentVersion=100;同见颜色:0x49: 域类型. 49 代表"I", 也就是Int.00 0D: 域名字长度.70 61 72 65 6E 74 56 65 72 73 69 6F 6E: parentVersion,域名字描述。

0x78: TC_ENDBLOCKDATA,对象块结束的标志。

0x70: TC_NULL, 说明没有其他超类的标志。

.到此为止,算法已经对所有的类的描述都做了输出。

下一步就是把实例对象的实际值输出了。

这时候是从parent Class的域开始的,见颜色:00 00 00 0A: 10, parentVersion域的值.还有SerialTest类的域:00 00 00 42: 66, version域的值.再往后的bytes比较有意思,算法需要描述contain类的信息,要记住,现在还没有对contain类进行过描述,见颜色:0x73: TC_OBJECT, 声明这是一个新的对象.0x72: TC_CLASSDESC声明这里开始一个新Class.00 07: 类名的长度.63 6F 6E 74 61 69 6E: contain,类名描述.FC BB E6 0E FB CB 60 C7: SerialVersionUID, 序列化ID.0x02: Various flags. 标记号. 该值声明该对象支持序列化00 01: 类内的域个数。

相关文档
最新文档