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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21920367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 11:24:25  来源:igfitidea点击:

Why when a constructor is annotated with @JsonCreator, its arguments must be annotated with @JsonProperty?

javajsonserializationHymanson

提问by Ori Popowski

In Hymanson, when you annotate a constructor with @JsonCreator, you must annotate its arguments with @JsonProperty. So this constructor

在 Hymanson 中,当您使用 注释构造函数时@JsonCreator,您必须使用 注释其参数@JsonProperty。所以这个构造函数

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

becomes this:

变成这样:

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

I don't understand why it's necessary. Can you please explain?

我不明白为什么有必要。你能解释一下吗?

采纳答案by Lukasz Wiktor

Hymanson has to know in what order to pass fields from a JSON object to the constructor. It is not possible to access parameter names in Java using reflection - that's why you have to repeat this information in annotations.

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

回答by Smutje

When I understand thiscorrectly, you replace the default constructor with a parameterized one and therefore have to describe the JSON keys which are used to call the constructor with.

当我正确理解这一点时,您将默认构造函数替换为参数化构造函数,因此必须描述用于调用构造函数的 JSON 键。

回答by Guy Bouallet

As precised in the annotation documentation, the annotation indicates that the argument name is used as the property name without any modifications, but it can be specified to non-empty value to specify different name:

注解文档中明确指出,该注解表示将参数名称作为属性名称,不做任何修改,但可以指定为非空值以指定不同的名称:

回答by lcfd

Because Java bytecode does not retain the names of method or constructor arguments.

因为 Java 字节码不保留方法或构造函数参数的名称。

回答by Manos Nikolaidis

It is possible to avoid constructor annotations with jdk8 where optionally the compiler will introduce metadata with the names of the constructor parameters. Then with Hymanson-module-parameter-namesmodule Hymanson can use this constructor. You can see an example at post Hymanson without annotations

可以避免使用 jdk8 的构造函数注释,其中编译器将可选地引入带有构造函数参数名称的元数据。然后使用Hymanson-module-parameter-names模块 Hymanson 可以使用这个构造函数。你可以在 post Hymanson 上看到一个没有注释的例子

回答by Rodrigo Quesada

Parameter names are normally not accessible by the Java code at runtime (because it's drop by the compiler), so if you want that functionality you need to either use Java 8's built-in functionality or use a library such as ParaNamer in order to gain access to it.

Java 代码在运行时通常无法访问参数名称(因为它由编译器删除),因此如果您想要该功能,您需要使用 Java 8 的内置功能或使用诸如 ParaNamer 之类的库以获得访问权限到它。

So in order to not having to utilize annotations for the constructor arguments when using Hymanson, you can make use of either of these 2 Hymanson modules:

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

Hymanson-module-parameter-names

Hyman逊模块参数名称

This module allows you to get annotation-free constructor arguments when using Java 8. In order to use it you first need to register the module:

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

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

Then compile your code using the -parameters flag:

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

javac -parameters ...

Link: https://github.com/FasterXML/Hymanson-modules-java8/tree/master/parameter-names

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

Hymanson-module-paranamer

Hyman逊模块参数

This other one simply requires you to register the module or configure an annotation introspection (but not both as pointed out by the comments). It allows you to use annotation-free constructor arguments on versions of Java prior to 1.8.

另一个只需要您注册模块或配置注释内省(但不是评论所指出的两者)。它允许您在 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 ParanamerOnHymansonAnnotationIntrospector());

Link: https://github.com/FasterXML/Hymanson-modules-base/tree/master/paranamer

链接:https: //github.com/FasterXML/Hymanson-modules-base/tree/master/paranamer

回答by letowianka

One can simply use java.bean.ConstructorProperties annotation - it's much less verbose and Hymanson also accepts it. For example :

可以简单地使用 java.bean.ConstructorProperties 注释 - 它不那么冗长,Hyman逊也接受它。例如 :

  import java.beans.ConstructorProperties;

  @ConstructorProperties({"answer","closed","language","interface","operation"})
  public DialogueOutput(String answer, boolean closed, String language, String anInterface, String operation) {
    this.answer = answer;
    this.closed = closed;
    this.language = language;
    this.anInterface = anInterface;
    this.operation = operation;
  }

回答by Andrew

Just come across it and got an answer somewhere. you can use below annotation since 2.7.0

只是遇到它并在某处得到答案。从 2.7.0 开始,您可以使用以下注释

@JsonAutoDetect(fieldVisibility = JsonAutoDetect.Visibility.ANY)
public class Point {
    final private double x;
    final private double y;

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