生产中,为什么很少用Java原生序列化转化成字节数组,而都建议用JSON/Avro/Protobuf
Java 原生序列化的问题
-
性能差
-
Java 自带的序列化是基于反射的,序列化时需要写入大量类元数据(类名、字段描述、版本号等),字节流臃肿。
-
反序列化时依赖反射和对象创建,速度比 Protobuf/Avro 慢一个数量级。
-
-
不跨语言
-
Java 序列化生成的字节流格式只有 JVM 认识,Python、Go、C++ 完全没法直接解析。
-
现代分布式系统(Kafka、RocketMQ、Spark、Flink)都追求多语言生态,Java 序列化天然不适合。
-
-
可演进性差
-
Java 原生序列化严重依赖类的
serialVersionUID
。 -
一旦类结构变化(比如加字段、删字段),旧数据往往无法反序列化,容易导致兼容性问题。
-
-
安全问题
-
反序列化漏洞(Java 反序列化攻击)是安全领域的经典问题。
-
恶意字节流可能触发远程代码执行 (RCE)。这也是很多中间件禁用 Java 原生序列化的原因。
-
-
可读性差
-
序列化后的字节流是二进制+类信息,几乎不可读,不方便调试和排查问题。
-
JSON/Avro/Protobuf 的优势
-
跨语言
-
JSON 是纯文本,任何语言都能解析。
-
Avro/Protobuf 有官方/第三方 SDK,Java/Python/Go/C++ 都支持。
-
-
高性能 & 小体积
-
Protobuf、Avro 属于二进制协议,比 JSON 更小更快。
-
比 Java 原生序列化小很多,网络传输更高效。
-
-
良好的 schema 演进性
-
Avro/Protobuf 支持 Schema 演进:可以在不影响旧数据的情况下新增字段、设置默认值。
-
在数据流里升级服务不会导致旧数据无法解析。
-
-
安全
-
没有 Java 反序列化漏洞。
-
数据是纯结构化存储,不会触发任意代码执行。
-
-
可读性
-
JSON 是纯文本,方便调试。
-
Avro/Protobuf 可以借助 Schema 工具解析,查看字段名和值。
-
举个对比表
序列化方式 | 体积大小 | 性能速度 | 跨语言 | 可演进性 | 可读性 | 安全性 |
---|---|---|---|---|---|---|
Java 原生 | 大 | 慢 | ❌ 不支持 | 差 | 差 | 弱(有漏洞) |
JSON | 较大 | 一般 | ✅ 支持 | 一般 | 强 | 强 |
Avro | 小 | 快 | ✅ 支持 | 强 | 中等 | 强 |
Protobuf | 最小 | 非常快 | ✅ 支持 | 强 | 较弱 | 强 |
实际使用场景
-
日志/配置/轻量数据 → JSON(方便人类可读)
-
大规模流式处理(Kafka/RocketMQ/Spark/Flink) → Avro 或 Protobuf(小 + 快 + 可演进)
-
跨语言 RPC(gRPC、Thrift) → Protobuf、Thrift
👉 所以总结:
生产环境不用 Java 原生序列化,是因为它慢、不兼容、不安全、扩展性差。
而 JSON/Avro/Protobuf 则能保证 跨语言、性能、兼容性、安全性,这就是主流选择。
转发请注明出处:https://www.cnblogs.com/fnlingnzb-learner/p/19073709