JSON.parseObject 构造方法陷阱
JSON.parseObject 构造方法陷阱详解
在使用 FastJSON 的 JSON.parseObject 方法时,构造方法的处理有几个关键陷阱需要注意,这些可能导致反序列化失败或数据丢失。
主要陷阱
1. 无参构造方法缺失陷阱
-
现象:反序列化时抛出
com.alibaba.fastjson.JSONException: default constructor not found -
原因:FastJSON 默认优先尝试调用无参构造方法
-
解决方案:
// 添加显式无参构造方法(即使类中没有字段) public MyClass() {}
2. 多构造方法歧义陷阱
-
现象:反序列化结果不符合预期,某些字段为null
-
原因:当存在多个构造方法时,FastJSON可能选择错误的构造方法
-
解决方案:
// 使用@JSONCreator明确指定应该使用的构造方法 @JSONCreator public MyClass(@JSONField(name = "field1") String field1, @JSONField(name = "field2") int field2) { //... }
3. 构造方法参数名丢失陷阱
-
现象:构造方法参数值全部为null或默认值
-
原因:Java字节码默认不保留参数名(除非编译时加了-parameters参数)
-
解决方案:
// 方案1:编译时添加-parameters参数(推荐) // 方案2:使用@JSONField注解明确指定参数对应JSON字段 @JSONCreator public MyClass(@JSONField(name = "jsonField1") String param1) { //... }
4. 不可变对象陷阱
-
现象:final字段反序列化失败
-
原因:FastJSON默认先创建对象再通过反射设值,与final字段冲突
-
解决方案:
// 必须通过构造方法初始化final字段 public class Immutable { private final String name; @JSONCreator public Immutable(@JSONField(name = "name") String name) { this.name = name; } }
5. 内部类构造陷阱
-
现象:反序列化内部类时抛出异常
-
原因:非静态内部类隐含需要外部类实例
-
解决方案:
// 方案1:改为静态内部类 public static class InnerClass {} // 方案2:提供外部类实例 ParserConfig.getGlobalInstance().putDeserializer(InnerClass.class, (parser, type, fieldName) -> { return outerInstance.new InnerClass(); });
最佳实践
-
显式定义无参构造方法:即使类中有其他构造方法
-
对复杂对象使用@JSONCreator:特别是当有无参构造方法但需要通过构造方法初始化时
-
编译保留参数名:在Maven/Gradle中配置:
<!-- Maven示例 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <compilerArgs> <arg>-parameters</arg> </compilerArgs> </configuration> </plugin> -
测试不同构造场景:特别是当类有多种构造方法时
-
考虑使用Builder模式:对于复杂对象,可以配合自定义反序列化器使用
浙公网安备 33010602011771号