Jackson默认反序列化机制四大核心疑问解答
默认情况下Jackson反序列化的工作机制及疑问
快速说明:我已阅读相关内容,但并未解答我所有疑问
注:此处指未进行额外开发操作:无注解、无自定义反序列化器等。
目前我了解到Jackson会寻找无参构造函数,随后通过setter方法(若无setter则通过反射)设置字段值。我有以下几个疑问:
- 无参构造函数必须是public修饰的吗?
// consider this public class Person { private int id; private String name; private Person() {} }
- 无参构造函数必须是唯一可用的构造函数吗?例如同时存在显式无参构造函数和全参构造函数时,会发生什么?
// consider this public class Person { private int id; private String name; public Person() {} public Person(int id, String name) { this.id = id; this.name = name; } }
- 如果没有无参构造函数,Jackson能否自动处理?它会选用全参构造函数吗?
// consider this public class Person { private int id; private String name; public Person(int id, String name) { this.id = id; this.name = name; } }
- 若构造函数未设置部分属性(假设有参构造函数仅设置部分属性),Jackson能否完成实例组装?它会调用可用的setter方法还是采用反射?
// consider this public class Person { private int id; private String name; public Person(String name) { this.name = name; } public void setId(int id) { this.id = id; } }
解答
1. 无参构造函数必须是public修饰的吗?
不需要。Jackson默认通过反射支持访问非public的无参构造函数(包括private、protected、包级访问权限),只要JVM安全策略允许反射操作即可。你提供的Person类可以被正常实例化,后续Jackson会通过反射直接设置id和name字段的值(因无setter方法)。
2. 无参构造函数必须是唯一可用的构造函数吗?
不是。当同时存在显式无参构造函数和全参构造函数时,Jackson默认优先选用无参构造函数实例化对象,之后通过setter方法或反射填充所有字段值,不会调用全参构造函数。
3. 如果没有无参构造函数,Jackson能否自动处理?它会选用全参构造函数吗?
默认情况下不能。Jackson找不到无参构造函数时会抛出JsonMappingException,提示无法定位合适的构造器。只有在添加注解(如@ConstructorProperties)或修改Jackson配置启用构造函数参数匹配时,才会自动使用全参构造函数,但你明确限定为无额外配置的默认场景,因此此时无法完成反序列化,会报错。
4. 若构造函数未设置部分属性,Jackson能否完成实例组装?它会调用可用的setter方法还是采用反射?
可以完成组装。Jackson的处理逻辑如下:
- 调用给定的有参构造函数实例化对象(即示例中的
public Person(String name)); - 对于未被构造函数初始化的属性(如
id),优先查找并调用对应的setter方法(即setId(int id)); - 若不存在对应setter方法,则通过反射直接设置字段值。
你的示例中,Jackson会先通过构造函数设置name,再调用setId填充id字段。
内容的提问来源于stack exchange,提问作者Sergey Zolotarev
相关产品推荐
相关产品推荐

