[BUG] Child Class Extended Fields Lost When Parent Class Was Serialized First
- Dominant language
- Java
- Stars
- 4.4k
- Forks
- 613
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 6
Description
### 问题描述
在序列化包含多态类型的对象时,fastjson2会根据第一次设置的属性值类型确定后续所有值的序列化类型,导致子类的扩展属性丢失。具体表现为:当某个属性第一次设置为父类实例后,即使后续赋值为子类实例,子类特有的字段也不会被序列化到JSON中。
### 环境信息
OS信息:Windows 10/Linux/macOS(均可复现)
JDK信息:OpenJDK 17
版本信息:Fastjson2 2.0.57
### 重现步骤
```java
public static void main(String[] args) {
class Message {
private String channel;
// getter/setter...
}
class AssignMessage extends Message {
private String assignee;
// getter/setter...
}
class TextMessage {
private Object data;
// getter/setter...
}
TextMessage textMsg = new TextMessage();
// 第一次设置父类实例
textMsg.setData(new Message());
System.out.println(JsonUtil.toJSON(textMsg));
// 第二次设置子类实例
AssignMessage am = new AssignMessage();
am.setAssignee("assignee");
textMsg.setData(am);
// 子类扩展属性丢失
System.out.println(JsonUtil.toJSON(textMsg));
}
```
实际结果
第二次输出的JSON中不包含子类特有的assignee字段:
```
{"data":{"channel":null}} // 丢失了assignee字段
```
### 期待的正确结果
应完整序列化子类所有字段:
```
{"data":{"channel":null,"assignee":"assignee"}}
```
问题分析
1. fastjson2在第一次序列化时缓存了data字段的类型信息(Message.class)
2. 后续序列化时直接使用缓存类型,忽略实际运行时类型(AssignMessage.class)
3. 导致子类扩展字段被忽略
### 相关日志输出
*请复制并粘贴任何相关的日志输出。*
#### 附加信息
调试发现错误代码:

Contributor guide
Research direction
Start with the JsonUtil.toJSON entry point and reproduce the behavior on Java 17 with fastjson2 2.0.57, serializing a parent instance before a subclass instance. Trace how the first value's type is reused during serialization. Done means the second JSON includes the subclass's assignee field, with a regression test covering both serializations.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100