@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 更适合可变对象,提供更灵活的映射方式。
相关推荐
IT枫斗者枫哥32 分钟前
MyBatis一对多分页:LIMIT 20,为什么凑不齐20个订单?
java·数据库
代码方舟32 分钟前
Java数据工程:利用天远全网运营商三要素优化线上实名认证合规体验
java·人工智能
BBmmo33 分钟前
我的 Java 学习笔记 · 第 7 篇:泛型与通配符
java
独泪了无痕33 分钟前
Hutool之RandomUtil:随机数生成的终极利器
java·后端
花开路口33 分钟前
深入理解 Java/Kotlin 协变与逆变
java·kotlin
运行时异常34 分钟前
【WMS 仓储系统集成 AI Agent 实战】第 7 讲:Vue3 前端工程化——Token 刷新锁、Markdown 渲染踩坑与权限体系
java
她的男孩35 分钟前
开放接口限流从 20 改到 200 还是每分钟 20 次:拆完防重放+幂等+限流,我找到 5 个静默失效的坑
java·后端·架构
天天被压力40 分钟前
【Python 量化取数指南 #13】Python 把行情落库:sqlite 一键存,回测随用随取
java·人工智能·python
天天被压力41 分钟前
【Python 量化取数指南 #14】Python 清洗行情数据:复权停牌对齐,回测不翻车
java·人工智能·python
独泪了无痕1 小时前
开发利器Hutool之MapUtil的使用
java·后端