为什么当构造函数用@JsonCreator注释时,其参数必须用@JsonProperty注释?

2022-08-31 07:58:21

在 Jackson 中,当您用 对构造函数进行注释时,必须使用 对构造函数的参数进行注释。所以这个构造函数@JsonCreator@JsonProperty

public Point(double x, double y) {
    this.x = x;
    this.y = y;
}

变成这个:

@JsonCreator
public Point(@JsonProperty("x") double x, @JsonProperty("y") double y) {
    this.x = x;
    this.y = y;
}

我不明白为什么这是必要的。您能解释一下吗?


答案 1

Jackson 必须知道以什么顺序将字段从 JSON 对象传递到构造函数。使用反射在Java中无法访问参数名称 - 这就是为什么您必须在注释中重复此信息的原因。


答案 2

Java代码通常无法在运行时访问参数名称(因为它被编译器删除),因此,如果您想要该功能,则需要使用Java 8的内置功能或使用ParanNamer等库才能访问它。

因此,为了在使用 Jackson 时不必对构造函数参数使用注释,您可以使用以下 2 个 Jackson 模块中的任何一个:

杰克逊模块参数名称

此模块允许您在使用 Java 8 时获取无注释的构造函数参数。为了使用它,你首先需要注册模块:

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new ParameterNamesModule());

然后使用 -parameters 标志编译代码:

javac -parameters ...

友情链接: https://github.com/FasterXML/jackson-modules-java8/tree/master/parameter-names

杰克逊-模块-帕拉纳默

另一个只需要您注册模块或配置注释内省(但不是注释中指出的两者)。它允许您在 1.8 之前的 Java 版本上使用无注释构造函数参数。

ObjectMapper mapper = new ObjectMapper();
// either via module
mapper.registerModule(new ParanamerModule());
// or by directly assigning annotation introspector (but not both!)
mapper.setAnnotationIntrospector(new ParanamerOnJacksonAnnotationIntrospector());

友情链接: https://github.com/FasterXML/jackson-modules-base/tree/master/paranamer