transient仅对Java原生序列化有效,用于跳过指定字段;未实现Serializable接口时无效,第三方JSON库处理方式取决于框架配置而非JVM。
transient 只对 Java 原生序列化起作用
它不是“禁止序列化”的万能开关,而是
/
在处理
类时的过滤规则:跳过被
修饰的字段。没实现
接口?加了
也毫无意义——根本不会触发序列化逻辑。
第三方 JSON 库(如 Jackson、FastJSON、Gson)默认通常忽略
字段,但这是框架自己的约定,不是 JVM 行为;你可以用
或
强制让它参与 JSON 序列化
字段本就不序列化,
是冗余写法,JVM 直接无视
字段反序列化后按类型默认值初始化(
→
,
→
),且无法在构造器中“补救”,因为反序列化不走构造器
哪些字段该加 transient?看三个硬标准
加
不是凭感觉,而是满足以下任一条件:
不该持久化:密码、token、临时
session
ID、密钥等敏感信息,明文落盘或跨网络传输等于裸奔
不能持久化:比如
、
、
等运行时资源,序列化后在另一 JVM 中必然失效,还会抛
不必持久化:缓存结果(
)、UI 组件引用、派生字段(如
,可由
重新计算)
反序列化后值丢了?别急着改字段,先看 readObject
字段反序列化后一定是默认值(
/
/
),但你可以在类里自定义恢复逻辑:
必须是
签名,且不能抛额外异常
务必调用
,否则非
字段也不会恢复
如果用了
,
就完全失效——因为整个序列化流程你全权控制,JVM 不再自动判断字段是否跳过
常见踩坑:你以为它生效了,其实根本没走序列化
很多开发者调试时发现
像没起作用,往往是因为:
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
立即学习
“
Java免费学习笔记(深入)
”;
误把 Spring 的
/
当成原生序列化——那是 Jackson 在干活,
默认有效,但若加了
就会覆盖它
Redis 缓存用的是
(原生)才认
;换成
后,行为由 Jackson 注解决定
字段是
+
,反序列化后值为
,但你又在 getter 里写了判空 fallback,导致误以为“它被恢复了”
真正关键的一点:
解决的是“要不要进
字节
流”,而不是“要不要进 JSON 字符串”或“要不要进数据库字段”。场景错配,再怎么加关键字也没用。
ObjectOutputStreamObjectInputStreamSerializabletransientSerializabletransienttransient@JsonProperty@JSONField(serialize = true)staticstatic transienttransientfinal transientStringnullint0transientThreadInputStreamConnectionNotSerializableExceptiontransient Map cache transient double totalPriceprice * qtytransientnull0falseprivate void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject(); // 先让 JVM 恢复非 transient 字段
this.password = "default_placeholder"; // 手动设值
this.cache = new HashMap<>(); // 重建不可序列化的对象
}private void readObject(ObjectInputStream)in.defaultReadObject()transientExternalizabletransienttransient@RequestBody@ResponseBodytransient@JsonPropertyJdkSerializationRedisSerializertransientGenericJackson2JsonRedisSerializerfinaltransientnulltransient