@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 更适合可变对象,提供更灵活的映射方式。
相关推荐
纪莫14 小时前
技术面:SpringBoot(springboot的类加载和传统的双亲委派有什么区别、如何按顺序实例化Bean)
java·spring·java面试⑧股
kyle~14 小时前
CPU调度---协程
java·linux·服务器·数据库·c++20
会飞的小蛮猪14 小时前
Skywalking运维之路(Skywalking服务搭建)
java·运维·监控
L.EscaRC15 小时前
Redisson在Spring Boot中的高并发应用解析
java·spring boot·后端
他们叫我技术总监15 小时前
从开发者视角深度评测:ModelEngine 与 AI 开发平台的技术博弈
java·人工智能·dubbo·智能体·modelengine
李辉200315 小时前
Python逻辑运算符
java·网络·python
摇滚侠15 小时前
Spring Boot3零基础教程,StreamAPI 介绍,笔记98
java·spring boot·笔记
扫地僧过江南15 小时前
Kanass零基础学习,如何进行任务管理
java·禅道·项目管理工具
无敌最俊朗@15 小时前
C++ 值类别与移动语义详解(精简版)
java·数据结构·算法
脸大是真的好~15 小时前
黑马JAVA+AI 加强14-2 网络编程-UDP和TCP通信-线程和线程池优化通信-BS架构原理
java