@JsonProperty 用于构造方法和属性

@JsonProperty 是 Jackson 库中的注解,用于指定 JSON 数据与 Java 对象之间的映射。它可以用在构造方法参数类属性上,但两者的行为和使用场景有所不同。


1. @JsonProperty 用在构造方法参数上

@JsonProperty 用在构造方法参数上时,Jackson 会使用该构造方法来反序列化 JSON 数据到 Java 对象。它会根据 JSON 数据中的字段名称匹配构造方法参数上的 @JsonProperty 注解。

特点:

  • 构造方法驱动的反序列化 :Jackson 会根据 JSON 数据调用带有 @JsonProperty 注解的构造方法来创建对象。
  • 不可变对象支持 :适用于不可变对象(final 属性)的场景,因为属性只能通过构造方法赋值。
  • 更安全的初始化:所有属性在对象创建时就被初始化,避免了后续的 setter 方法调用。

示例:

java 复制代码
public class UserInfo {
    private final String userType;
    private final PhoneNumber phoneNumber;

    public UserInfo(@JsonProperty("userType") final String userType,
                    @JsonProperty("phoneNumber") final PhoneNumber phoneNumber) {
        this.userType = userType;
        this.phoneNumber = phoneNumber;
    }
}

JSON 数据

java 复制代码
{
  "userType": "admin",
  "phoneNumber": {
    "countryCode": "+1",
    "number": "1234567890"
  }
}

反序列化过程

  • Jackson 会解析 JSON 数据,并根据 @JsonProperty 注解找到对应的构造方法参数。
  • 调用构造方法 UserInfo(String userType, PhoneNumber phoneNumber, String nuId) 创建对象。

2. @JsonProperty 用在属性上

@JsonProperty 用在类属性上时,Jackson 会通过默认的无参构造方法创建对象,然后通过反射调用属性的 setter 方法(或直接访问字段)来设置值。

特点:

  • 基于默认构造方法的反序列化:需要类有一个无参构造方法(如果没有显式定义,Java 会提供一个默认的无参构造方法)。
  • 支持可变对象:适用于需要通过 setter 方法或直接修改属性值的场景。
  • 更灵活的映射:可以直接在属性上定义 JSON 字段名称,避免在构造方法中显式声明。

示例:

java 复制代码
public class UserInfo {
    @JsonProperty("userType")
    private String userType;

    @JsonProperty("phoneNumber")
    private PhoneNumber phoneNumber;

    // 无参构造方法
    public UserInfo() {}

    // Getters and Setters
}

JSON 数据

java 复制代码
{
  "userType": "admin",
  "phoneNumber": {
    "countryCode": "+1",
    "number": "1234567890"
  }
}

反序列化过程

  • Jackson 会调用无参构造方法创建 UserInfo 对象。
  • 根据 @JsonProperty 注解找到对应的 JSON 字段,并通过反射设置属性值。

3. 两者的主要区别

特性 用在构造方法参数上 用在属性上
对象创建方式 使用带注解的构造方法创建对象 使用无参构造方法创建对象
适用场景 不可变对象(final 属性) 可变对象
依赖的构造方法 必须有带 @JsonProperty 注解的构造方法 必须有无参构造方法
灵活性 需要在构造方法中定义所有需要的属性 可以在类中定义部分或全部属性
性能 构造方法反序列化性能稍高(少一次反射调用) 通过反射设置属性,性能稍低
代码风格 更适合不可变对象和构造方法初始化的场景 更适合传统的 Java Bean 风格

4. 如何选择

  • 使用构造方法参数上的 @JsonProperty

    • 如果类是不可变的(final 属性)。
    • 如果希望在对象创建时就完成所有属性的初始化。
    • 如果类没有无参构造方法,或者不希望提供无参构造方法。
  • 使用属性上的 @JsonProperty

    • 如果类是可变的(需要 setter 方法或直接修改属性)。
    • 如果需要更灵活的 JSON 映射。
    • 如果类需要与传统的 Java Bean 风格兼容。

5. 总结

  • 构造方法上的 @JsonProperty 更适合不可变对象,确保对象在创建时就被完全初始化。
  • 属性上的 @JsonProperty 更适合可变对象,提供更灵活的映射方式。
相关推荐
码语智行1 分钟前
导入模板下载
java
摇滚侠13 分钟前
IDEA 创建 Java 项目 推送到远程 Git 仓库
java·git·intellij-idea
可乐ea17 分钟前
【知识获取与分享社区项目 | 项目日记第 24 天】终章总结:从认证、发布、计数、Feed、搜索到 RAG:完整复盘一个知识社区后端系统
java·spring boot·redis·mysql·elasticsearch·ai·kafka
Jabes.yang24 分钟前
Java面试实录:AIGC场景下的Stream、微服务、Redis、Kafka与安全实战
java·spring boot·redis·微服务·面试·kafka·aigc
lwf00616425 分钟前
实战:用 Java 模拟登录阿里云控制台,爬取没有 OpenAPI 的数据
java·阿里云
程序员二叉36 分钟前
【Java】 面试核心合集:BigDecimal、缓存池、多态、反射全解析
java·缓存·面试
Full Stack Developme40 分钟前
SpringMVC multipart 文件上传
java·开发语言
西凉的悲伤1 小时前
Spring Security + JWT 登录认证完整实践指南
java·后端·spring·spring security·jwt
晚笙coding1 小时前
从零讲透 LangChain 输出格式化:让模型真的“能用”
java·开发语言·langchain
奋斗的小方1 小时前
Java进阶篇1-1:异常
java·开发语言·python