如何为不可变类创建默认构造函数 [英] How to create default constructor for immutable class
问题描述
我喜欢根据本文(为什么对象必须是不可变的)。
但是,我试图使用Jackson Object Mapper解析一个对象。我最初得到 JsonMappingException:找不到类型[simple type,class]的合适构造函数:无法从JSON对象实例化。
However, I am trying to parse an object using Jackson Object Mapper. I was initially getting JsonMappingException: No suitable constructor found for type [simple type, class ]: cannot instantiate from JSON object.
我可以按照这里,提供默认构造函数并使我的字段不是最终的。
I could fix it as mentioned here, by providing a default constructor and making my fields non-final.
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.NonNull;
@AllArgsConstructor
// @NoArgsConstructor(access = AccessLevel.PRIVATE)
@Builder
@Data
public class School {
@NonNull
private final String schoolId;
@NonNull
private final String schoolName;
}
为了克服这个问题,我应该遵循什么样的编程风格?唯一的方法是让我的对象变得可变吗?
What is a good programming style that I should follow to overcome this problem? Is the only way around is to make my objects mutable?
我可以使用不使用默认构造函数的其他映射器吗?
Can I use a different mapper that does not use the default constructor?
推荐答案
您可以使用杰克逊工厂(使用 @ JsonCreator )从地图上读取字段并调用非默认构造函数:
You can use a Jackson factory (method annotated with @JsonCreator) that reads fields off a map and calls your non-default constructor:
class School {
//fields
public School(String id, String name) {
this.schoolId = id;
this.schoolName = name;
}
@JsonCreator
public static School create(Map<String, Object> object) {
return new School((String) object.get("schoolId"),
(String) object.get("schoolName"));
}
//getters
}
Jackson将使用json的 Map
版本调用 create
方法。这有效地解决了这个问题。
Jackson will call the create
method with a Map
version of the json. And this effectively solves the problem.
我相信你的问题是寻找杰克逊的解决方案,而不是新的模式/风格。
I believe your question looks for a Jackson solution, rather than a new pattern/style.
这篇关于如何为不可变类创建默认构造函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!