transient 关键字用于标记字段不参与默认序列化,防止敏感数据泄露;修饰后反序列化时字段为默认值,但对自定义序列化、第三方库及内存转储无效。

transient 关键字用于标记类中的字段,告诉 Java 序列化机制:该字段**不参与默认的序列化过程**。它常被用来防止敏感数据(如密码、密钥、临时计算结果等)在对象序列化时被意外写入文件、网络流或缓存中。
为什么需要 transient?
Java 默认序列化(如实现 Serializable 接口后调用 ObjectOutputStream.writeObject())会递归保存对象所有非静态、非瞬态(non-transient)字段的值。如果字段包含密码字符串、会话 token、数据库连接等,直接序列化可能造成安全泄露或运行时异常(比如序列化不可序列化的资源对象)。
如何正确使用 transient 修饰字段
只需在字段声明前加上 transient 关键字即可:
- 适用于实例变量(不能修饰 static 或 final 字段——static 本就不序列化,final 字段若可被初始化则仍可能被序列化,但加 transient 无意义且编译通过,不推荐)
- 修饰后,反序列化时该字段值为对应类型的默认值(如 null、0、false)
- 示例:
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private transient String password; // 不会被序列化
private transient Token authToken; // 假设 Token 不可序列化,避免 InvalidClassException
}
注意:transient 不是万能的安全屏障
transient 只影响默认序列化机制,以下情况仍可能导致敏感字段暴露:
- 若类自定义了 writeObject() 和 readObject() 方法,且在其中手动写入/读取了被标记为 transient 的字段,则该字段仍会被序列化
- 使用 JSON、XML 等第三方序列化库(如 Jackson、Gson)时,transient 默认不生效(需额外配置,如 Jackson 的 @JsonIgnore)
- 内存转储(heap dump)、日志打印、调试器查看等场景,transient 完全无效
进阶建议:配合自定义序列化控制敏感字段
若需更精细控制(例如序列化前加密 password,反序列化后重新生成),可结合 transient 与自定义序列化方法:
- 将敏感字段声明为 transient
- 重写 private void writeObject(ObjectOutputStream out),仅序列化脱敏后的数据(如哈希摘要)或跳过写入
- 重写 private void readObject(ObjectInputStream in),反序列化后按需恢复(如从配置重建 token)或保持为 null










