Record 实现 Serializable 之后,反序列化走哪条路径?构造器里的校验会不会生效?数据结构演进时哪些改动兼容?这篇用真实写入、读取的两个进程验证。
(读取端进程里没有执行过 new P 与 new R)普通 Serializable 类 P:反序列化后 P.calls = 0(构造器没有被调用,字段由序列化机制直接写入);record R:R.calls = 1(canonical 构造器被调用了) 读到的值:P.x = 1,R.x = 1
类 P:构造器有校验,但流里写的是 age=-5 → 读出 age = -5(校验被绕过,对象处于非法状态) record R:InvalidObjectException: age < 0;cause = IllegalArgumentException: age < 0
增加组件 c(long) → 读出 R[a=7, b=hello, c=0] 增加组件 c(String) → 读出 R[a=7, b=hello, c=null] 删除组件 b → 读出 R[a=7] 组件 b 改名为 name → 读出 R[a=7, name=null] 调换组件顺序 → 读出 R[b=hello, a=7] 组件 a 的类型 int → long → InvalidClassException: R; incompatible types for field a 组件 a 的类型 int → Integer → InvalidClassException: R; incompatible types for field a 显式 serialVersionUID 1 → 2(其它不变)→ 读出 R[a=7, b=hello] 对照:普通类 显式 serialVersionUID 1 → 2 → InvalidClassException: P; local class incompatible: stream classdesc serialVersionUID = 1, local class serialVersionUID = 2 record 未声明 serialVersionUID 时,ObjectStreamClass.lookup(R.class).getSerialVersionUID() = 0
--- 写入端的输出 --- [Q.writeReplace 被调用] --- 读取端的输出 --- R 读出 R[a=1, b=x](上面如果没有 [R.readObject 被调用],说明 record 里的 writeObject/readObject 被忽略) [Proxy.readResolve 被调用] Q 读出 Q[a=2, b=y]