序列化和json

本文对比了PHP中序列化与JSON编码方式,在字符串长度及处理效率上的差异,并探讨了它们各自适用的应用场景。

转载自:http://www.phppan.com/2011/03/serialize-json/

【序列化的概念】

序列化是将对象状态转换为可保持或可传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

将对象的状态信息转换为可以存储或传输的窗体的过程。 在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

通常,对象实例的所有字段都会被序列化,这意味着数据会被表示为实例的序列化数据。这样,能 够解释该格式的代码有可能能够确定这些数据的值,而不依赖于该成员的可访问性。类似地,反序列化从序列化的表示形式中提取数据,并直接设置对象状态,这也 与可访问性规则无关。 对于任何可能包含重要的安全性数据的对象,如果可能,应该使该对象不可序列化。如果它必须为可序列化的,请尝试生成特定字段来保存不可序列化的重要数据。 如果无法实现这一点,则应注意该数据会被公开给任何拥有序列化权限的代码,并确保不让任何恶意代码获得该权限。

【JSON的概念】

JSON,JavaScript Object Notation,一种更轻、更友好的用于接口(AJAX、REST等)数据交换的格式。 JSON是结构化数据串行化的文本格式,作为XML的一种替代品,用于表示客户端与服务器间数据交换有效负载的格式。它是从ECMAScript语言标准 衍生而来的。JSON的设计目标是使它成为小的、轻便的、文本的,而且是JavaScript的一个子集。

【长度的比较】

如下一段代码,显示了对数组和对象编码后生成的字符串及其长度

输出:

很明显的长度区别,serialize在编码后大概是json的两倍

原因:

  • serialize后字符串包含了子串的长度,这可能是速度方面的优化,典型的空间换时间 ,但是它本身还是太重了。
  • serialize有更加详细的类型区分,而json只有四种类型,并且是以简单的符号表示。

【速度的比较】

以代码说明问题,如下比较速度的代码:

输出:

serialize的速度在大数据量的情况下比json差了快一个数量级。

从上面两点看,json不管是在速度还是在生成的字符串的大小上都比serialize要好,那为什么serialize还要存在呢? 原因在下面这个点:实现的功能。

【处理对象】

如下代码:

输出:

json无法处理对象方法等数据。

【使用范围】

  • 序列化使用serialize,特别是对象的存储。这是其存在的意义。
  • 与对象无关的数据存储可以使用json,如包含大量数字的数组等。只是当遇到这种情况,我们需要做的可能是重构数据库了。
  • 数据交换时使用JSON,这也是其定义所在。
  • 目前JSON是能用于UTF-8编码的数据。
### Java 序列化 JSON 序列化的性能及适用场景比较 #### 数据格式适用场景 Java 原生序列化是一种专为 Java 语言设计的二进制序列化机制,其主要优势在于能够保留对象的完整类型信息,并支持复杂的对象图结构。它适用于需要在 Java 系统内部进行对象持久化或远程调用的场景,例如 Java RMI(Remote Method Invocation)或 Java EE 应用服务器之间的对象传输 [^1]。 JSONJavaScript Object Notation)是一种轻量级的文本数据交换格式,具有良好的可读性跨语言兼容性。JSON 序列化适用于需要跨平台、跨语言交互的场景,例如 RESTful Web 服务、微服务之间的通信、前端后端的数据交换等 [^1]。由于 JSON 是一种通用格式,因此它在现代分布式系统中广泛使用,例如使用 `com.cedarsoftware` 的 `json-io` 库进行 Java 对象 JSON 之间的高效转换 [^1]。 #### 性能对比 Java 原生序列化的性能通常优于 JSON 序列化,特别是在序列化/反序列化大型对象图时。其原因在于 Java 原生序列化使用二进制格式,数据紧凑,序列化后的字节数量较少,解析速度更快。相比之下,JSON 是文本格式,数据体积较大,且需要进行字符串解析,因此在性能上通常较慢 [^1]。 然而,JSON 序列化的性能可以通过使用高效的库(如 Jackson、Gson 或 json-io)来显著提升。这些库通过优化序列化过程减少内存开销,使得 JSON 序列化的性能接近甚至在某些场景下超越 Java 原生序列化 [^1]。 #### 安全性兼容性 Java 原生序列化在安全性方面存在一定的风险,尤其是在反序列化不可信的数据时,可能会导致任意代码执行漏洞。因此,在需要处理不受信任数据的场景中,应谨慎使用 Java 原生序列化。而 JSON 序列化本质上更安全,因为它仅传输数据结构,不包含类定义或执行逻辑 。 JSON 序列化在版本兼容性方面也更具优势。Java 原生序列化对类结构的变更非常敏感,若序列化数据的类版本当前类不一致,则可能导致反序列化失败。为了解决这个问题,Java 提供了 `serialVersionUID` 机制来控制版本一致性 [^3]。相比之下,JSON 序列化通常通过字段名进行映射,即使类结构发生部分变更,也可以通过默认值或可选字段的方式保持兼容性 。 #### 使用示例:Java 原生序列化 ```java import java.io.*; class Person implements Serializable { private static final long serialVersionUID = 1L; private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } } public class JavaSerializationExample { public static void main(String[] args) { try { // 序列化 Person person = new Person("Alice", 30); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("person.ser")); oos.writeObject(person); oos.close(); // 反序列化 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("person.ser")); Person deserializedPerson = (Person) ois.readObject(); ois.close(); System.out.println("Deserialized: " + deserializedPerson); } catch (Exception e) { e.printStackTrace(); } } } ``` #### 使用示例:JSON 序列化(使用 Jackson) ```java import com.fasterxml.jackson.databind.ObjectMapper; class Person { private String name; private int age; // 构造函数、getter setter public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } } public class JsonSerializationExample { public static void main(String[] args) { try { ObjectMapper mapper = new ObjectMapper(); Person person = new Person("Alice", 30); // 序列化 String json = mapper.writeValueAsString(person); System.out.println("Serialized: " + json); // 反序列化 Person deserialized = mapper.readValue(json, Person.class); System.out.println("Deserialized: " + deserialized); } catch (Exception e) { e.printStackTrace(); } } } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值