跳转到主内容
趣航编程网 - 趣学编程,启航技术之路!

在Java里transient关键字的作用是什么_Java序列化控制说明

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 cache
)、UI 组件引用、派生字段(如
transient double totalPrice
,可由
price * qty
重新计算) 反序列化后值丢了?别急着改字段,先看 readObject
transient
字段反序列化后一定是默认值(
null
/
0
/
false
),但你可以在类里自定义恢复逻辑:
private 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()
,否则非
transient
字段也不会恢复 如果用了
Externalizable
transient
就完全失效——因为整个序列化流程你全权控制,JVM 不再自动判断字段是否跳过 常见踩坑:你以为它生效了,其实根本没走序列化 很多开发者调试时发现
transient
像没起作用,往往是因为: Eclipse导入Android或其他的JAVA项目的正确方法 WORD版 本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看 下载 立即学习 “ Java免费学习笔记(深入) ”; 误把 Spring 的
@RequestBody
/
@ResponseBody
当成原生序列化——那是 Jackson 在干活,
transient
默认有效,但若加了
@JsonProperty
就会覆盖它 Redis 缓存用的是
JdkSerializationRedisSerializer
(原生)才认
transient
;换成
GenericJackson2JsonRedisSerializer
后,行为由 Jackson 注解决定 字段是
final
+
transient
,反序列化后值为
null
,但你又在 getter 里写了判空 fallback,导致误以为“它被恢复了” 真正关键的一点:
transient
解决的是“要不要进 字节 流”,而不是“要不要进 JSON 字符串”或“要不要进数据库字段”。场景错配,再怎么加关键字也没用。

相关文章