深拷贝怎么实现?这个Java序列化工具类7个方法带类白名单

简介: 本工具类提供安全、可控的Java对象深拷贝与序列化功能:支持`deepCopy()`独立副本、`serializeToBytes()`/`toBase64()`双向转换,及带白名单校验的`deserialize()`/`fromBase64()`,严格防范反序列化漏洞,要求JDK 17+。

📋 目录

一、工具类功能

把对象转成字节或 Base64 文本再还原,或者复制出一份引用完全独立的副本,嵌套集合与数组一起断开、改副本不影响原对象,读外部来路的字节必须给类白名单。

二、所需环境

JDK 17或以上

三、方法与调用示例(按需调用)

🔢 方法序号:1

🎯 方法用途:

  • 序列化再读出,得到引用完全独立的副本,嵌套对象、集合与数组一起复制
  • 不想手写拷贝构造、又要改掉副本不影响原对象时用

🧩 方法定义:public static <T extends Serializable> T deepCopy(T source)

🗣️ 入参解释:public static <T extends Serializable> T deepCopy(待拷贝对象)

📤 返回值解释:T,与原对象同类型的新副本

💡 边界口径:

  • transient 字段不会被带走,副本里是 null
  • 拷贝后 == 不再成立,但 equals 语义保持;单例与枚举要用各自的克隆策略
  • 原对象的 writeObject 副作用会被执行,持有连接或文件的对象不适合走这条路
  • 对象图里有任何一个类没实现 Serializable 就整体失败,抛 IllegalStateException
  • 副本走的是免白名单的内部读取,外部来路的数据绝不能用这个入口

🧪 方法示例:

  • deepCopy(origin).tags.size() 拿到 2 个,原对象仍是 1 个,集合互不影响
  • 副本的地址城市改成上海后,原对象读到的是 杭州
  • 刚拷出来的副本 sessionToken 是 null,transient 字段没带过来
  • deepCopy(null) 抛 IllegalArgumentException

🔢 方法序号:2

🎯 方法用途:

  • 把对象转成 Java 原生序列化的字节数组
  • 进程内缓存、同版本服务之间的临时传递用这一版

🧩 方法定义:public static byte[] serializeToBytes(Object object)

🗣️ 入参解释:public static byte[] serializeToBytes(可序列化对象)

📤 返回值解释:byte[],Java 序列化协议的字节流

💡 边界口径:

  • 字节流前两个字节固定是 magic 0xaced,一眼能认出是 Java 序列化数据
  • 对象没实现 Serializable 时抛 IllegalStateException,消息里带上类名
  • 参数为 null 抛 IllegalArgumentException
  • 原生序列化格式对类版本变更极敏感,改字段或改 serialVersionUID 就解不出来,也不具备跨语言能力

🧪 方法示例:

  • serializeToBytes(origin).length 拿到 367
  • 头两个字节拿到 magic 0xaced
  • serializeToBytes(new Object()) 抛 对象序列化为字节数组失败,class=java.lang.Object, java.lang.Object

🔢 方法序号:3

🎯 方法用途:

  • 把对象转成一串 Base64,能放进字符串字段、日志行或文本消息
  • 只能传文本的通道(表单字段、MQ 文本消息)用它承载对象

🧩 方法定义:public static String toBase64(Object object)

🗣️ 入参解释:public static String toBase64(可序列化对象)

📤 返回值解释:String,标准 Base64(含 padding)

💡 边界口径:

  • 前缀 rO0AB 就是 Java 序列化流的特征头,看到它应知道这是原生序列化数据
  • 长度约为字节数的 4 分之 3,比字节更占空间
  • 编码规则沿用 Base64.getEncoder(),是标准字母表,不是 URL 安全形态
  • 还原必须走带白名单的 fromBase64,别拿它当可信任字符串处理

🧪 方法示例:

  • toBase64(origin).length() 拿到 492
  • 前 20 位拿到 rO0ABXNyAC5jb20uZXhh,一看就是序列化流
  • 对一段文本 toBase64("只是一段文本") 也能出串,拿它按 Order.class 还原会抛 反序列化结果类型不匹配,期望 com.example.order.api.SerializeUtilsDemo$Order,实际 java.lang.String

🔢 方法序号:4

🎯 方法用途:

  • 读外部来路的字节,白名单之外的类在读任何对象之前就被拒绝
  • 网络、上传、缓存、MQ 来的序列化数据必须走这个带白名单的入口

🧩 方法定义:public static Object deserialize(byte[] bytes, String allowedClassPattern)

🗣️ 入参解释:public static Object deserialize(字节数组, 类白名单表达式)

📤 返回值解释:Object,还原出的对象,由调用方自己判类型

💡 边界口径:

  • 用的是 JDK 的 ObjectInputFilter,在读取任何对象之前就拒绝非法类
  • 表达式末尾会自动补一条 !* 兜底拒绝,没匹配到的类不会被放过
  • 同时限制深度 64 层、引用数 100 万、字节量 256 MiB、数组长度 1000 万
  • 对象图里的嵌套类也要显式放行,只放外层类会在内层被拒
  • 「被过滤器拒绝」与「字节流损坏」是两回事,前者翻译成 IllegalArgumentException,不会混成一句流损坏

🧪 方法示例:

  • 白名单里没有 java.awt.Point 时 deserialize(foreign, pattern) 抛 反序列化被安全过滤器拒绝(类不在白名单内,或超出深度/引用数/数组长度上限): InvalidClassException: filter status: REJECTED
  • 同一份字节把 java.awt.** 写进白名单后拿到 java.awt.Point[x=1,y=2]
  • 漏写兜底拒绝规则时会被自动补齐,非法类依然抛 IllegalArgumentException
  • 对象图深度超过 64 层时抛 IllegalArgumentException
  • deserialize(new byte[0], MY_PACKAGE) 抛 bytes 不能为null或空数组
  • deserialize(bytes, " ") 抛 allowedClassPattern 不能为null或空白

🔢 方法序号:5

🎯 方法用途:

  • 还原自己刚序列化出来的字节,不做类白名单校验
  • 数据源百分百可信、且就是本进程 serializeToBytes 产出的场合用它

🧩 方法定义:public static Object deserializeTrusted(byte[] bytes)

🗣️ 入参解释:public static Object deserializeTrusted(本类刚产出的字节)

📤 返回值解释:Object,还原出的对象

💡 边界口径:

  • 名字里的 Trusted 就是提醒:换数据源必须改成带白名单的 deserialize
  • 仍然带深度、引用数、字节量与数组长度限制,防爆与深链
  • 字节流损坏、类不存在或版本不一致抛 IllegalStateException 并保留原因
  • 参数为 null 或空数组抛 IllegalArgumentException

🧪 方法示例:

  • deserializeTrusted(bytes) 拿到 单号 ORD20261005001
  • 还原结果与原对象的 equals 判断是 true
  • 与原对象是否同一个引用,答案是 false
  • deserializeTrusted(new byte[0]) 抛 bytes 不能为null或空数组

🔢 方法序号:6

🎯 方法用途:

  • 从 Base64 还原并校验类型,直接拿到目标类的对象,不用自己强转
  • 前端或外部系统回传的 Base64 对象串,按约定类型解回来时用

🧩 方法定义:public static <T> T fromBase64(String base64, Class<T> type, String... extraAllowed)

🗣️ 入参解释:public static <T> T fromBase64(Base64串, 目标类, 额外白名单)

📤 返回值解释:T,类型校验通过后的对象

💡 边界口径:

  • 白名单除目标类外,还放行 java.lang.*、java.util.**、java.time.**、java.math.** 这些基础包
  • 业务对象所在的包要靠 extraAllowed 追加,漏了就在过滤器处被拒
  • 解出来的对象类型与 type 不符时抛 IllegalArgumentException,消息带上期望与实际类型
  • Base64 串非法或空白抛 IllegalArgumentException
  • 要更紧的口径就自己写表达式走 deserialize

🧪 方法示例:

  • fromBase64(base64, Order.class, MY_PACKAGE) 拿到 ORD20261005001,金额 4999,地址 杭州
  • 对象图里的嵌套类没放行时抛 反序列化被安全过滤器拒绝(类不在白名单内,或超出深度/引用数/数组长度上限): InvalidClassException: filter status: REJECTED
  • 把一段文本的 Base64 按 Order.class 解,抛 反序列化结果类型不匹配,期望 com.example.order.api.SerializeUtilsDemo$Order,实际 java.lang.String

🔢 方法序号:7

🎯 方法用途:

  • 不指定目标类,完全按调用方给的白名单表达式从 Base64 还原
  • 类型要运行时才知道、或者要一次放开多个包时用这一版

🧩 方法定义:public static Object fromBase64(String base64, String allowedClassPattern)

🗣️ 入参解释:public static Object fromBase64(Base64串, 类白名单表达式)

📤 返回值解释:Object,还原出的对象,类型由调用方判断

💡 边界口径:

  • 表达式口径与 deserialize(byte[], String) 完全一致,同样自动补 !*
  • 不做类型校验,需要类型安全就用三参版
  • 表达式为 null 或空白抛 IllegalArgumentException

🧪 方法示例:

  • fromBase64(base64, MY_PACKAGE + ";" + JDK_ONLY) 拿到还原对象的类名 Order
  • 表达式里没有目标类所在的包时抛 IllegalArgumentException,消息是过滤器拒绝那句

四、工具类源码(可直接复制)

📦 源码文件

相关文章
|
5天前
|
JavaScript API iOS开发
DeepSeek Harness下载、安装、配置一篇搞定(2026整理,送常用插件)
DeepSeek Harness(DSH)是DeepSeek于2026年开源的MIT协议AI Agent框架,支持插件化组装模型、工具、沙箱与UI,兼容主流大模型。本文提供免Node.js的桌面端安装包(Win/macOS),含详细图文教程及热门插件推荐。
2117 13
|
云安全 安全 网络安全
|
5天前
|
iOS开发 Docker MacOS
【2026实测】Docker Desktop下载、安装、汉化、配置教程(附官网安装包)
Docker Desktop 是 Docker 官方推出的桌面容器管理工具,集成引擎、CLI、图形界面与 Kubernetes,支持 Win/macOS/Linux。2026 最新版 4.88.1 强化 ARM 原生运行、镜像加速及资源可视化,附中文汉化与国内镜像配置指南。
919 1
|
18天前
|
人工智能 API 开发工具
DeepSeek Harness 神插件:白嫖 13 家大厂模型
`dsh-our-free-model` 是 DeepSeek Harness 神级插件:零配置、零API Key、零账号,聚合13家大厂免费模型(含DeepSeek V4.1 Flash、Kimi K3等),支持本地网关、用量看板与自动降级,真正实现“白嫖即用”。
3068 49
|
11天前
|
JavaScript 安全 前端开发
Nodejs Brotli decoder 代码执行漏洞 (CVE-2026-111497)10629
Node.js发布安全更新修复Brotli解码器高危RCE漏洞(CVE-2026-111497),建议受影响版本用户立即升级。
2108 2
|
5天前
|
安全 算法 定位技术
《高性价比人生指南》完整原版:普通人用最少的资源,过好这一生的底层逻辑~How To Live Better
📖《高性价比人生指南》是一份基于实证、拒绝焦虑的生存手册,倡导以“人生时薪”为视角,重新计算时间、金钱与精力的成本与收益。它不承诺逆袭,只教人算清账:省下的钱若耗掉时间便亏;买体验比买物品更值;睡眠是最高杠杆的健康投资;关系贵在情绪价值而非表面热络;学习重在改变行为而非自我安慰。核心理念:用低成本、高回报的微小行动,换取长期的选择权——不是成为谁,而是掌控自己人生的主动权。
|
10天前
|
人工智能 JSON Linux
【保姆级】ComfyUI部署教程(下载+安装+配置+工作流,2026最新)
ComfyUI 是一款开源节点式AI生成工具,支持图像、视频、音频及3D内容创作。通过拖拽连线组合模型加载、提示词、采样等节点,构建可复用、易修改的工作流,兼容SD1.5、SDXL、Flux、Qwen Image等主流模型。
|
4天前
|
Linux 开发工具 iOS开发
Codex保姆级教程(下载+安装+登录+使用,含所有版本,2026最新)
Codex是OpenAI推出的开源AI编程智能体,本地运行,可理解整个代码库,支持自然语言指令改代码、执行命令、跑测试、修Bug,兼容Win/macOS/Linux。(239字)