Java 中 Object 类怎么在进行对象序列化时通过重写方法控制特定字段的传输

冷炫風刃

冷炫風刃

2026-08-04

946人浏览

原创

java中控制序列化需在自定义类重写private void writeobject(objectoutputstream)和readobject,配合defaultwriteobject或putfields实现字段定制;多次发送需调用reset避免引用缓存。

java 中 object 类怎么在进行对象序列化时通过重写方法控制特定字段的传输

Java 中 Object 类本身不能也不需要重写序列化方法——它不是被序列化的主体,而是所有类的父类。真正起作用的是你自定义的类,只要它参与序列化,就可以通过重写特定私有方法来控制字段传输。

关键点很明确:控制权不在 Object,而在你自己的类里,且必须用对的方法签名和调用时机。


必须重写 private void writeObject

只有在你的类中声明一个严格匹配签名的私有方法:

private void writeObject(ObjectOutputStream out) throws IOException

JVM 才会在序列化该类实例时自动调用它,跳过默认的反射式字段扫描。这是整个控制逻辑的入口。

  • 方法必须是 private,不能是 publicprotected
  • 参数类型必须是 ObjectOutputStream,不能多也不能少
  • 必须抛出 IOException
  • 不能返回值(void

一旦存在这个方法,ObjectOutputStream.defaultWriteObject() 就不会自动执行,除非你主动调用它。


两种主流控制方式:defaultWriteObject + 手动写,或 putFields

✅ 方式一:先 defaultWriteObject(),再手动加密/跳过字段

适合想保留大部分字段默认行为,只干预个别敏感字段(如 password):

private void writeObject(ObjectOutputStream out) throws IOException {
    // 1. 写入所有非 transient、非 static 字段(默认行为)
    out.defaultWriteObject();

    // 2. 单独处理 transient 字段(比如加密后写入)
    if (this.password != null) {
        byte[] encrypted = encrypt(this.password);
        out.writeInt(encrypted.length);
        out.write(encrypted);
    } else {
        out.writeInt(0);
    }
}

配套必须重写 readObject,按相同顺序读取并解密赋值。

Java JDK 25
Java JDK 25

Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。

下载

✅ 方式二:用 putFields() 显式指定每个字段值

适合需要统一加工、兼容旧格式、或强制写入 transient 字段:

private void writeObject(ObjectOutputStream out) throws IOException {
    ObjectOutputStream.PutField fields = out.putFields();
    fields.put("username", this.username);
    fields.put("age", this.age);
    fields.put("password", hashPassword(this.password)); // 即使 password 是 transient,也能写入
    out.writeFields(); // 必须调用,否则什么也不发生
}

注意:

  • putFields() 后未 put 的字段,仍会按当前内存值写入(不是 null0
  • 字段名必须与类中声明的完全一致(大小写敏感)
  • static 字段设值无效;transient 字段可通过此方式强制写入

别漏掉 readObject —— 序列化和反序列化必须对称

写了自定义 writeObject,就必须配对写 readObject,否则反序列化时字段为空或错乱:

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
    ObjectInputStream.GetField fields = in.readFields();
    this.username = (String) fields.get("username", "");
    this.age = fields.get("age", 0);
    String hashedPass = (String) fields.get("password", "");
    this.password = recoverFromHash(hashedPass); // 或直接赋值
}

或者配合方式一的写法,用 in.readInt() + in.read() 按顺序读取加密数据。


额外提醒:避免引用缓存导致字段“不更新”

如果对象通过 Socket 反复发送(比如心跳包、状态推送),ObjectOutputStream 默认会缓存对象引用,导致后续修改的字段没真正写出去。解决办法很简单:

out.writeObject(myObj);
out.reset(); // 清空引用缓存,确保下次完整序列化

否则即使字段值变了,客户端收到的仍是旧值——这是线上常见却难定位的问题。

不复杂但容易忽略。

Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南

相关专题

更多
java
java

Java是一个通用术语,用于表示Java软件及其组件,包括“Java运行时环境 (JRE)”、“Java虚拟机 (JVM)”以及“插件”。php中文网还为大家带了Java相关下载资源、相关课程以及相关文章等内容,供大家免费下载使用。

2023.06.15

3768

6

java正则表达式语法
java正则表达式语法

java正则表达式语法是一种模式匹配工具,它非常有用,可以在处理文本和字符串时快速地查找、替换、验证和提取特定的模式和数据。本专题提供java正则表达式语法的相关文章、下载和专题,供大家免费下载体验。

2023.07.05

2776

9

java自学难吗
java自学难吗

Java自学并不难。Java语言相对于其他一些编程语言而言,有着较为简洁和易读的语法,本专题为大家提供java自学难吗相关的文章,大家可以免费体验。

2023.07.31

2802

8

java配置jdk环境变量
java配置jdk环境变量

Java是一种广泛使用的高级编程语言,用于开发各种类型的应用程序。为了能够在计算机上正确运行和编译Java代码,需要正确配置Java Development Kit(JDK)环境变量。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.01

637

3

java保留两位小数
java保留两位小数

Java是一种广泛应用于编程领域的高级编程语言。在Java中,保留两位小数是指在进行数值计算或输出时,限制小数部分只有两位有效数字,并将多余的位数进行四舍五入或截取。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

2023.08.02

601

3

java基本数据类型
java基本数据类型

java基本数据类型有:1、byte;2、short;3、int;4、long;5、float;6、double;7、char;8、boolean。本专题为大家提供java基本数据类型的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

705

5

java有什么用
java有什么用

java可以开发应用程序、移动应用、Web应用、企业级应用、嵌入式系统等方面。本专题为大家提供java有什么用的相关的文章、下载、课程内容,供大家免费下载体验。

2023.08.02

1290

5

java在线网站
java在线网站

Java在线网站是指提供Java编程学习、实践和交流平台的网络服务。近年来,随着Java语言在软件开发领域的广泛应用,越来越多的人对Java编程感兴趣,并希望能够通过在线网站来学习和提高自己的Java编程技能。php中文网给大家带来了相关的视频、教程以及文章,欢迎大家前来学习阅读和下载。

2023.08.03

18844

3

配置java环境变量
配置java环境变量

配置Java环境变量是为了让操作系统能够识别和使用Java的相关命令和功能。本专题为大家提供配置java环境变量相关文章,帮助大家解决问题。

2023.08.03

646

8

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Java JDBC数据库连接官方教程
Java JDBC数据库连接官方教程

共0课时 | 0人学习

Java 26官方文档
Java 26官方文档

共0课时 | 0人学习