transient仅对java原生序列化有效,用于跳过指定字段;未实现serializable接口时无效,第三方json库处理方式取决于框架配置而非jvm。
transient 只对 Java 原生序列化起作用
它不是“禁止序列化”的万能开关,而是 ObjectOutputStream / ObjectInputStream 在处理 Serializable 类时的过滤规则:跳过被 transient 修饰的字段。没实现 Serializable 接口?加了 transient 也毫无意义——根本不会触发序列化逻辑。
- 第三方 JSON 库(如 Jackson、FastJSON、Gson)默认通常忽略
transient字段,但这是框架自己的约定,不是 JVM 行为;你可以用@JsonProperty或@JSONField(serialize = true)强制让它参与 JSON 序列化 -
static字段本就不序列化,static transient是冗余写法,JVM 直接无视transient -
final transient字段反序列化后按类型默认值初始化(String→null,int→0),且无法在构造器中“补救”,因为反序列化不走构造器
哪些字段该加 transient?看三个硬标准
加 transient 不是凭感觉,而是满足以下任一条件:
- 不该持久化:密码、token、临时 session ID、密钥等敏感信息,明文落盘或跨网络传输等于裸奔
- 不能持久化:比如
Thread、InputStream、Connection等运行时资源,序列化后在另一 JVM 中必然失效,还会抛NotSerializableException - 不必持久化:缓存结果(
transient Map<string object> cache</string>)、UI 组件引用、派生字段(如transient double totalPrice,可由price * qty重新计算)
反序列化后值丢了?别急着改字段,先看 readObject
transient 字段反序列化后一定是默认值(null / 0 / false),但你可以在类里自定义恢复逻辑: