@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 更适合可变对象,提供更灵活的映射方式。
相关推荐
韩师学子--小倪3 小时前
fastjson与gson的toString差异
java·json
Drawing stars3 小时前
JAVA后端 前端 大模型应用 学习路线
java·前端·学习
nbsaas-boot3 小时前
SQL Server 存储过程开发规范(公司内部模板)
java·服务器·数据库
行百里er3 小时前
用 ThreadLocal + Deque 打造一个“线程专属的调用栈” —— Spring Insight 的上下文管理术
java·后端·架构
玄〤4 小时前
黑马点评中 VoucherOrderServiceImpl 实现类中的一人一单实现解析(单机部署)
java·数据库·redis·笔记·后端·mybatis·springboot
J_liaty4 小时前
Spring Boot拦截器与过滤器深度解析
java·spring boot·后端·interceptor·filter
亲爱的非洲野猪5 小时前
Java锁机制八股文
java·开发语言
rgeshfgreh5 小时前
C++字符串处理:STL string终极指南
java·jvm·算法
Zoey的笔记本5 小时前
「支持ISO27001的GTD协作平台」数据生命周期管理方案与加密通信协议
java·前端·数据库
lpfasd1235 小时前
Spring Boot 4.0.1 时变更清单
java·spring boot·后端